﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Controls;
using System.Xml;
using SHomeWorkshop.LunarConcept.ModifingManager;
using System.Windows;
using SHomeWorkshop.LunarConcept.Tools;
using System.Windows.Media;
using System.Windows.Documents;
using System.IO;
using System.ComponentModel;
using System.Windows.Media.Imaging;
using SHomeWorkshop.LunarConcept.Widgets;
using SHomeWorkshop.LunarConcept.Converters;
using SHomeWorkshop.LunarConcept.Widgets.Interfaces;

namespace SHomeWorkshop.LunarConcept.Controls
{
    /// <summary>
    /// 创建时间：2011年12月26日
    /// 创建者：  杨震宇
    /// 
    /// 主要用途：用于在主界面中管理各页（一个页就是一个PageEditor）。
    /// 
    /// ★★注意：此类中的操作不应记录“修改项”——所有记录都应在各个“自定义命令”的Execute()方法中调用。
    /// </summary>
    public class EditorManager : AdornerDecorator, IModifingManager<Action, ModifingInfo>, INotifyPropertyChanged
    {
        #region 构造方法=====================================================================================================

        /// <summary>
        /// EditorManager类的构造方法。
        /// </summary>
        /// <param name="masterWindow"></param>
        public EditorManager(MainWindow masterWindow)
        {
            //=========================================
            //注意：不能让MainWindow的MainScrollViewer使用Padding来分割出一片区域。
            //      那看起来就和页面缩小了一样。
            this.Margin = new Thickness(10);
            //=========================================

            this.LayoutTransform = this.scaleTransform;

            this.masterWindow = masterWindow;
            this.Child = this.mainStackPanel;
            this.HorizontalAlignment = HorizontalAlignment.Center;
            this.VerticalAlignment = VerticalAlignment.Center;

            //初始化“修改项”列表。
            modifingItemsList = new ModifingList<Action, ModifingInfo>(this);
            modifingItemsList.RedoExecuted +=
                new EventHandler<ModifingEventArgs<Action, ModifingInfo>>
                    (modifingItemsList_RedoExecuted);
            modifingItemsList.UndoExecuted +=
                new EventHandler<ModifingEventArgs<Action, ModifingInfo>>
                    (modifingItemsList_UndoExecuted);

            this.BuildAssistLineBrushes();//pageEditor需要此画刷。

            //必须在this.InitilizeDocument();前面：读取默认页面尺寸
            var paperSizeName = Globals.ConfigManager.Get(XmlTags.PaperSizeTag);
            if (string.IsNullOrEmpty(paperSizeName) == false)
            {
                var defPaperInfo = PaperInfo.GetPaperInfo(paperSizeName);
                this.DefPaperInfo = defPaperInfo;
            }

            //会“重置ModifingItemsList”。因此注意顺序。
            this.InitilizeDocument();

            this.mainStackPanel.SizeChanged += new SizeChangedEventHandler(mainStackPanel_SizeChanged);

            this.magnifier.Height = this.magnifier.Width = 200;
            this.magnifier.BorderBrush = this.widgetSelectionAdornerBrush;
            this.magnifier.BorderThickness = new Thickness(2);
            Xceed.Wpf.Toolkit.MagnifierManager.SetMagnifier(this, this.magnifier);

        }

        void mainStackPanel_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            RefreshPaginations();
        }

        #endregion

        #region 索引器=======================================================================================================

        /// <summary>
        /// 索引器。取mainStackPanel中的某个编辑器。
        /// 
        /// 异常：
        ///      IndexOutOfRangeException
        /// </summary>
        /// <param name="index">要取的编辑器的。索引。</param>
        /// <returns>极为意外的情况下会返回null。</returns>
        public PageEditor this[int index]
        {
            get { return this.mainStackPanel.Children[index] as PageEditor; }
        }

        #endregion

        #region 字段与属性===================================================================================================

        /// <summary>
        /// 放大镜。
        /// </summary>
        private Xceed.Wpf.Toolkit.Magnifier magnifier = new Xceed.Wpf.Toolkit.Magnifier() { Visibility = Visibility.Collapsed };

        /// <summary>
        /// [只读]放大镜。
        /// </summary>
        public Xceed.Wpf.Toolkit.Magnifier Magnifier
        {
            get { return this.magnifier; }
        }

        public UIElementCollection Children
        {
            get { return mainStackPanel.Children; }
        }

        /// <summary>
        /// 返回编辑器的数目。
        /// </summary>
        public int Count { get { return this.mainStackPanel.Children.Count; } }

        /// <summary>
        /// 是否连续插入部件。
        /// 如果此值为假，应在主窗口的editorManager_MouseLeftButtonDroped事件处理器结束前将主窗口的
        /// 几个“添加”部件ToggleButton的IsChecked值设置为假！
        /// 并将MouseDraggingType设置为None。
        /// </summary>
        private bool continueInsertWidget = false;
        /// <summary>
        /// 是否连续添加线型部件。
        /// </summary>
        public bool ContinueInsertWidget
        {
            get { return continueInsertWidget; }
            set { continueInsertWidget = value; }
        }

        private Brush documentBackground = Brushes.White;  //BrushManager.DefaultImageBrush;
        /// <summary>
        /// [只读]文档默认背景色。
        /// 
        /// ★注意：因为背景色较复杂。因此不应直接使用这个属性的set访问器。
        /// ——而应借用DefaultBackgroundText来更改此属性值。
        /// </summary>
        public Brush DocumentBackground
        {
            get
            {
                return documentBackground;
            }
        }

        private TileMode defaultBackTileMode = TileMode.FlipXY;
        /// <summary>
        /// 翻转模式。
        /// </summary>
        public TileMode DefaultBackTileMode
        {
            get { return defaultBackTileMode; }
            set
            {
                defaultBackTileMode = value;
                if (this.xmlDocument != null && this.xmlDocument.DocumentElement != null)
                {
                    this.xmlDocument.DocumentElement.
                        SetAttribute(XmlTags.DefaultBackTileModeTag, defaultBackTileMode.ToString());
                }

                ImageBrush iBsh = this.documentBackground as ImageBrush;
                if (iBsh != null)
                {
                    iBsh.TileMode = defaultBackTileMode;
                }

                this.RefreshDocumentBackground();
            }
        }

        private string documentBackgroundText;
        /// <summary>
        /// 会设置“DocumentBackground”。
        /// </summary>
        public string DocumentBackgroundText
        {
            get
            {
                return this.documentBackgroundText;
            }
            set
            {
                this.documentBackgroundText = value;

                Brush bsh = BrushManager.Parse(documentBackgroundText);
                this.documentBackground = bsh;

                ImageBrush iBsh = bsh as ImageBrush;
                if (iBsh != null)
                {
                    iBsh.TileMode = this.defaultBackTileMode;
                }

                this.RefreshDocumentBackground();

                if (this.xmlDocument != null && this.xmlDocument.DocumentElement != null)
                {
                    this.xmlDocument.DocumentElement.
                        SetAttribute(XmlTags.DocumentBackgroundTag, this.documentBackgroundText);
                }

                if (masterWindow != null)
                {
                    masterWindow.RefreshPageView();
                }
            }
        }

        /// <summary>
        /// [只读]根据默认字号来决定默认字体。WPF在处理文本时，15号以下会出现模糊的问题。
        /// </summary>
        public string DefaultFontName
        {
            get
            {
                if (defaultFontSize > 15) return "Microsoft YaHei";
                else return "SimSun";
            }
        }

        private double defaultFontSize = 12;
        /// <summary>
        /// [读写]设置当前文档默认字号。最小值为12。设置小于12的值会自动当成12处理。
        /// </summary>
        public double DefaultFontSize
        {
            get { return defaultFontSize; }
            set
            {
                if (value < 12)
                {
                    defaultFontSize = 12;
                }
                else
                {
                    defaultFontSize = value;
                }

                defaultFontSize = value;
                if (this.xmlDocument != null && this.xmlDocument.DocumentElement != null)
                {
                    this.xmlDocument.DocumentElement.
                        SetAttribute(XmlTags.DefaultFontSizeTag, defaultFontSize.ToString());
                }

                this.RefreshDefaultFontSize();
            }
        }

        private Orientation defPaperDirection = Orientation.Vertical;
        /// <summary>
        /// 页面的方向。
        /// </summary>
        public Orientation DefPaperDirection
        {
            get
            {
                return defPaperDirection;
            }

            set
            {
                defPaperDirection = value;

            }
        }

        private PaperInfo defPaperInfo = PaperInfo.GetPaperInfo("A4");   //("slide");
        /// <summary>
        /// [读写]默认纸张类型信息。纸张类型信息不包含纸张方向信息。
        /// </summary>
        public PaperInfo DefPaperInfo
        {
            get { return this.defPaperInfo; }
            set
            {
                this.defPaperInfo = value;
            }
        }

        public void RefreshDefaultPaperDirectionAndSize()
        {
            var pages = this.GetAllPageEditors();
            foreach (var page in pages)
            {
                page.RefreshPaperDirectionAndSize();
            }
        }

        //2012年6月14日。与部件本身相关的，改由“部件样式”决定，不再使用单独的属性。
        //private Brush defaultForeground = Brushes.Black;
        ///// <summary>
        ///// 文档中的文本的默认色彩。
        ///// </summary>
        //public Brush DefaultForeground
        //{
        //    get
        //    {
        //        return defaultForeground;
        //    }
        //    set
        //    {
        //        defaultForeground = value;

        //        if (this.xmlDocument != null && this.xmlDocument.DocumentElement != null)
        //        {
        //            this.xmlDocument.DocumentElement.
        //                SetAttribute(XmlTags.DefaultForegroundTag, Tools.BrushManager.GetName(this.defaultForeground));
        //        }

        //        this.RefreshDefaultForeground();
        //    }
        //}

        /// <summary>
        /// [只读]返回默认文件短名（用在保存文件时的对话框中）。
        /// </summary>
        public string DefaultShortFileName
        {
            get
            {
                if (fullPathOfDiskFile == null || fullPathOfDiskFile.Length <= 0) return string.Empty;

                int index = fullPathOfDiskFile.LastIndexOf('\\');
                if (index < 0) return string.Empty;

                char lastChar = fullPathOfDiskFile[fullPathOfDiskFile.Length - 1];

                if (lastChar == '\\' || lastChar == '\r' ||
                    lastChar == '\t' || lastChar == '\n' || lastChar == ':')
                    return string.Empty;

                string shortFileName = fullPathOfDiskFile.Substring(index + 1);

                return shortFileName.Trim();
            }
        }

        /// <summary>
        /// [读写]主面板指向。默认垂直。
        /// </summary>
        public Orientation Direction
        {
            get { return this.mainStackPanel.Orientation; }
            set
            {
                this.mainStackPanel.Orientation = value;

                foreach (var ue in this.mainStackPanel.Children)
                {
                    var page = ue as PageEditor;
                    page?.AddPageAdorner?.InvalidateVisual();
                    page?.CopyPageAdorner?.InvalidateVisual();
                }
            }
        }

        /// <summary>
        /// 返回找到的第一个PageEditor。
        /// </summary>
        public PageEditor FirstPageEditor
        {
            get
            {
                for (int i = 0; i < this.mainStackPanel.Children.Count; i++)
                {
                    UIElement ue = this.mainStackPanel.Children[i];
                    PageEditor pe = ue as PageEditor;

                    if (pe == null) { i++; continue; }

                    return pe;
                }

                return null;
            }
        }

        private FormatBrush formatBrush = null;
        /// <summary>
        /// [读写]格式刷。
        /// </summary>
        public FormatBrush FormatBrush
        {
            get { return formatBrush; }
            set { formatBrush = value; }
        }

        private string fullPathOfDiskFile;
        /// <summary>
        /// [读写]表示当前文档所对应的磁盘文件的全路径。
        /// </summary>
        public string FullPathOfDiskFile
        {
            get { return fullPathOfDiskFile; }
            set
            {
                FullPathOfDiskFileChangedEventArgs e = new FullPathOfDiskFileChangedEventArgs();
                e.OldFullPathOfDiskFile = fullPathOfDiskFile;
                e.NewFullPathOfDiskFile = value;

                fullPathOfDiskFile = value;

                //触发FullPathOfDiskFileChanged事件
                OnFullPathOfDiskFileChanged(this, e);

                if (masterWindow != null)
                {
                    masterWindow.Title = Globals.AppName + "-" + fullPathOfDiskFile;
                }
            }
        }

        /// <summary>
        /// 返回找到的最后一个PageEditor。
        /// </summary>
        public PageEditor LastPageEditor
        {
            get
            {
                for (int i = this.mainStackPanel.Children.Count - 1; i >= 0; i--)
                {
                    UIElement ue = this.mainStackPanel.Children[i];
                    PageEditor pe = ue as PageEditor;

                    if (pe == null) { i--; continue; }

                    return pe;
                }

                return null;
            }
        }

        /// <summary>
        /// 用以承载各PageEditor的面板。本类其实就是对它的功能的一个封装！
        /// ——因此，它是private的。
        /// </summary>
        private StackPanel mainStackPanel = new StackPanel() { Orientation = Orientation.Vertical, Background = Brushes.Transparent, };

        public event EventHandler<MainSelectedPageEditorChangedEventArgs> MainSelectedPageChanged;
        /// <summary>
        /// 这个用public，因为需要从PageEditor接收消息。
        /// </summary>
        public void OnMainSelectedPageChanged(object sender, MainSelectedPageEditorChangedEventArgs e)
        {
            if (MainSelectedPageChanged != null)
            {
                MainSelectedPageChanged(sender, e);
            }
        }

        private MainWindow masterWindow;
        /// <summary>
        /// [只读]本包装编辑器所在的主窗口。
        /// </summary>
        public MainWindow MasterWindow
        {
            get { return masterWindow; }
        }

        private Enums.PageDraggingType mouseDraggingType = Enums.PageDraggingType.None;

        /// <summary>
        /// 这里很复杂。
        /// 
        /// 主界面的几个“添加（插入）线型部件”的按钮将决定这个属性的值。
        /// 此属性的值会影响所属的所有PageEditor的MouseInfo.DraggingType值。
        /// 
        /// 而PageEditor.MouseInfo.DraggingType又会影响PageEditor提供的三个事件：
        ///     MouseLeftButtonDroped/WidgetControlerMoved/WidgetMoved，
        ///     而这三个事件又会引发EdiorManager的三个同名事件，
        ///     EditorManager的三个同名事件在主窗口的代码隐藏文件中进行事件处理，分别调用：
        ///     InsertStraitLineWidgetCommand/……/InsertRectangleLineWidgetCommand等算定义命令类的Execute()方法，
        ///     ——具体调用哪个自定义命令类（添加哪种线型部件）由PageEditor.MouseInfo.DraggingType决定
        ///     ——而PageEditor.MouseInfo.DraggingType值又由【本属性的值】决定
        ///     ——这样就实现了添加线型部件
        ///     又会调用MoveWidgetControlerCommand的Execute()方法,
        ///     ——这样就实现了拖动控制点
        ///     还会调用MoveWidgetCommand的Execute()方法，
        ///     ——这样就实现了拖动部件
        /// 
        /// PageEditor.MouseInfo.Dragging属性的值【并不一定】受制于此属性值：
        /// 事实上，PageEditor在进行“拖动控制点”和“拖动部件”这两种操作时，不会受此值影响。
        /// 但“拖动控制点”和“拖动部件”结束时，PageEditor.MouseInfo.Dragging值会被重置为此属性的值。
        /// </summary>
        public Enums.PageDraggingType MouseDraggingType
        {
            get { return mouseDraggingType; }
            set
            {
                this.mouseDraggingType = value;
                foreach (UIElement ue in this.mainStackPanel.Children)
                {
                    PageEditor pe = ue as PageEditor;
                    if (pe == null) continue;

                    pe.MouseInfo.DraggingType = value;
                }
            }
        }

        private Orientation orientation = Orientation.Vertical;
        /// <summary>
        /// 编辑器指向。这个不是页面纸型的指向，而是所有页面之间如何排列（只有一个页面编辑器时，纵、横向效果相同）。
        /// </summary>
        public Orientation Orientation
        {
            get { return orientation; }
            set
            {
                orientation = value;
                if (this.xmlDocument.DocumentElement != null)
                {
                    this.xmlDocument.DocumentElement.SetAttribute("Orientation", orientation.ToString());
                }

                this.mainStackPanel.Orientation = value;
            }
        }

        /// <summary>
        /// [只读]页面数目。
        /// </summary>
        public int PageCount
        {
            get
            {
                if (this.mainStackPanel == null) return 0;
                int count = 0;
                foreach (UIElement ue in this.mainStackPanel.Children)
                {
                    if (ue is PageEditor) count++;
                }
                return count;
            }
        }

        private string pageFooter = string.Empty;
        /// <summary>
        /// 页脚文本。
        /// </summary>
        public string PageFooter
        {
            get { return pageFooter; }
            set
            {
                pageFooter = value;
                if (this.xmlDocument != null && this.xmlDocument.DocumentElement != null)
                {
                    this.xmlDocument.DocumentElement.SetAttribute(XmlTags.PageFooterTag, value);
                }

                this.RefreshPageFooter();
            }
        }

        private string pageHeader = string.Empty;
        /// <summary>
        /// 页眉文本。
        /// </summary>
        public string PageHeader
        {
            get { return pageHeader; }
            set
            {
                pageHeader = value;
                if (this.xmlDocument != null && this.xmlDocument.DocumentElement != null)
                {
                    this.xmlDocument.DocumentElement.SetAttribute(XmlTags.PageHeaderTag, value);
                }

                this.RefreshPageHeader();
            }
        }

        private bool isShowPageNumber = true;
        /// <summary>
        /// 是否显示页码。
        /// </summary>
        public bool IsShowPageNumber
        {
            get { return isShowPageNumber; }
            set
            {
                isShowPageNumber = value;
                if(this.xmlDocument !=null && this.xmlDocument.DocumentElement != null)
                {
                    this.xmlDocument.DocumentElement.SetAttribute(XmlTags.IsShowPageNumberTag, value.ToString());
                }

                this.RefreshPaginations();
            }
        }

        /// <summary>
        /// [只读]取当前文档的“PageSet”节点。意外情况下可能返回null。一般不应出现此情况。
        /// </summary>
        public XmlNode PageSetNode
        {
            get
            {
                if (this.xmlDocument == null || this.xmlDocument.DocumentElement == null) return null;

                XmlNode pageSetNode = this.xmlDocument.DocumentElement.SelectSingleNode(XmlTags.PageSetTag);

                return pageSetNode;
            }
        }

        private Dialogs.ReplaceDialog replaceBox = null;
        /// <summary>
        /// [只读]替换框。这样设计是为了暂存上次替换的各关键词。直到关闭文档或程序才真正释放。
        /// </summary>
        public Dialogs.ReplaceDialog ReplaceBox
        {
            get
            {
                if (replaceBox == null)
                    replaceBox = new Dialogs.ReplaceDialog(masterWindow, this);

                return replaceBox;
            }
        }

        private ScaleTransform scaleTransform = new ScaleTransform();
        /// <summary>
        /// [只读]用于进行缩放的形变属性。
        /// ——主窗口应添加对此Transform的ScalX和ScalY的绑定。
        /// </summary>
        public ScaleTransform ScaleTransform
        {
            get { return scaleTransform; }
        }

        private Brush widgetStartControlerBrush = Brushes.Red;
        /// <summary>
        /// 文档中的线型部件的首控制点的默认色彩。
        /// </summary>
        public Brush WidgetStartControlerBrush
        {
            get
            {
                return widgetStartControlerBrush;
            }
            set
            {
                widgetStartControlerBrush = value;
                if (this.xmlDocument != null && this.xmlDocument.DocumentElement != null)
                {
                    this.xmlDocument.DocumentElement.SetAttribute(XmlTags.WidgetStartControlerBrush,
                        BrushManager.GetName(widgetStartControlerBrush));
                }

                this.RefreshWidgetSelectionAdornerBrush();
            }
        }

        private Brush widgetCenterControlerBrush = Brushes.Yellow;
        /// <summary>
        /// 文档中的线型部件的中控制点的默认色彩。
        /// </summary>
        public Brush WidgetCenterControlerBrush
        {
            get
            {
                return widgetCenterControlerBrush;
            }
            set
            {
                widgetCenterControlerBrush = value;
                if (this.xmlDocument != null && this.xmlDocument.DocumentElement != null)
                {
                    this.xmlDocument.DocumentElement.SetAttribute(XmlTags.WidgetCenterControlerBrush,
                        BrushManager.GetName(widgetCenterControlerBrush));
                }

                this.RefreshWidgetSelectionAdornerBrush();
            }
        }

        private Brush widgetEndControlerBrush = Brushes.Blue;
        /// <summary>
        /// 文档中的线型部件的尾控制点的默认色彩。
        /// </summary>
        public Brush WidgetEndControlerBrush
        {
            get
            {
                return widgetEndControlerBrush;
            }
            set
            {
                widgetEndControlerBrush = value;
                if (this.xmlDocument != null && this.xmlDocument.DocumentElement != null)
                {
                    this.xmlDocument.DocumentElement.SetAttribute(XmlTags.WidgetEndControlerBrush,
                        BrushManager.GetName(widgetEndControlerBrush));
                }

                this.RefreshWidgetSelectionAdornerBrush();
            }
        }

        private Brush widgetSelectionAdornerBrush = Brushes.Blue;
        /// <summary>
        /// 文档中的部件的的默认选定框色。
        /// </summary>
        public Brush WidgetSelectionAdornerBrush
        {
            get
            {
                return widgetSelectionAdornerBrush;
            }
            set
            {
                widgetSelectionAdornerBrush = value;
                if (this.xmlDocument != null && this.xmlDocument.DocumentElement != null)
                {
                    this.xmlDocument.DocumentElement.SetAttribute(XmlTags.WidgetSelectionAdornerBrush,
                        BrushManager.GetName(widgetSelectionAdornerBrush));
                }

                this.RefreshWidgetSelectionAdornerBrush();
            }
        }

        private XmlDocument xmlDocument = new XmlDocument()
        {
            PreserveWhitespace = false,
            //如果保留空白，会出现莫名其妙的空白节点！！！
            //但如果为false，不保留空白，又会造成文本中的空格被忽略。因此：
            //在Widget的文本节点中使用：paragraphSetNode.SetAttribute("xml:space", "preserve");//防止空格失效！
        };
        /// <summary>
        /// [读写]整个概念图Xml后台文档。
        /// </summary>
        public XmlDocument XmlDocument
        {
            get { return xmlDocument; }
            set
            {
                this.CloseDocument();
                this.xmlDocument = value;
                this.Build();
            }
        }

        #endregion

        #region 样式属性=======================================================================================

        private WidgetStyle textAreaStyle = new WidgetStyle(typeof(Widgets.TextArea).Name);
        public WidgetStyle TextAreaStyle
        {
            get { return this.textAreaStyle; }
            set
            {
                this.textAreaStyle = value;
                if (this.xmlDocument != null && this.xmlDocument.DocumentElement != null)
                {
                    this.xmlDocument.DocumentElement.SetAttribute(XmlTags.TextAreaStyleTag, value.ToString());
                }
            }
        }

        private WidgetStyle pictureBoxStyle = new WidgetStyle(typeof(Widgets.PictureBox).Name);
        public WidgetStyle PictureBoxStyle
        {
            get { return this.pictureBoxStyle; }
            set
            {
                this.pictureBoxStyle = value;
                if (this.xmlDocument != null && this.xmlDocument.DocumentElement != null)
                {
                    this.xmlDocument.DocumentElement.SetAttribute(XmlTags.PictureBoxStyleTag, value.ToString());
                }
            }
        }

        private WidgetStyle groupStyle = new WidgetStyle(typeof(Widgets.GroupWidget).Name);

        public WidgetStyle GroupStyle
        {
            get { return groupStyle; }
            set
            {
                groupStyle = value;
                if (this.xmlDocument != null && this.xmlDocument.DocumentElement != null)
                {
                    this.xmlDocument.DocumentElement.SetAttribute(XmlTags.GroupStyleTag, value.ToString());
                }
            }
        }

        private WidgetStyle straitLineStyle = new WidgetStyle(typeof(Widgets.StraitLineWidget).Name);

        public WidgetStyle StraitLineStyle
        {
            get { return straitLineStyle; }
            set
            {
                straitLineStyle = value;
                if (this.xmlDocument != null && this.xmlDocument.DocumentElement != null)
                {
                    this.xmlDocument.DocumentElement.SetAttribute(XmlTags.StraitLineStyleTag, value.ToString());
                }
            }
        }

        //private AssistGridForm assistGridForm = AssistGridForm.Box;
        /// <summary>
        /// [读写]是否显示风格线。默认只显示为Box。不随文档保存。
        /// </summary>
        //[Obsolete("此属性已于2014年2月5日被弃用")]
        //public AssistGridForm AssistGridForm
        //{
        //    get { return assistGridForm; }
        //    set
        //    {
        //        assistGridForm = value;
        //        if (this.xmlDocument != null && this.xmlDocument.DocumentElement != null)
        //        {
        //            this.xmlDocument.DocumentElement.SetAttribute(XmlTags.AssistGridFormTag, value.ToString());
        //        }
        //        //this.RefreshAssistGridForm();
        //    }
        //}

        private DrawingBrush assistGridLinesBrush;
        /// <summary>
        /// [只读]页面编辑区域（辅助线）背景画刷。
        /// </summary>
        public DrawingBrush AssistGridLinesBrush
        {
            get { return assistGridLinesBrush; }
        }

        private DrawingBrush assistMiziLinesBrush;
        /// <summary>
        /// [只读]页面编辑区域（米字格辅助线）背景画刷。
        /// </summary>
        public DrawingBrush AssistMiziLinesBrush
        {
            get { return assistMiziLinesBrush; }
        }

        private DrawingBrush assistHuiziLinesBrush;
        /// <summary>
        /// [只读]页面编辑区域（回宫格辅助线）背景画刷。
        /// </summary>
        public DrawingBrush AssistHuiziLinesBrush
        {
            get { return assistHuiziLinesBrush; }
        }

        private DrawingBrush assistTianziLinesBrush;
        /// <summary>
        /// [只读]页面编辑区域（田字格辅助线）背景画刷。
        /// </summary>
        public DrawingBrush AssistTianziLinesBrush
        {
            get { return assistTianziLinesBrush; }
        }

        private WidgetStyle bezierLineStyle = new WidgetStyle(typeof(Widgets.BezierLineWidget).Name);

        public WidgetStyle BezierLineStyle
        {
            get { return bezierLineStyle; }
            set
            {
                bezierLineStyle = value;
                if (this.xmlDocument != null && this.xmlDocument.DocumentElement != null)
                {
                    this.xmlDocument.DocumentElement.SetAttribute(XmlTags.BezierLineStyleTag, value.ToString());
                }
            }
        }

        private WidgetStyle polyLineStyle = new WidgetStyle(typeof(Widgets.PolyLineWidget).Name);

        public WidgetStyle PolyLineStyle
        {
            get { return polyLineStyle; }
            set
            {
                polyLineStyle = value;
                if (this.xmlDocument != null && this.xmlDocument.DocumentElement != null)
                {
                    this.xmlDocument.DocumentElement.SetAttribute(XmlTags.PolyLineStyleTag, value.ToString());
                }
            }
        }

        private List<string> previewMainSelectedWidgetIDs = new List<string>();
        /// <summary>
        /// [只读]前一个活动部件的ID。用于删除部件后，选定回到上次的活动部件。
        /// </summary>
        public List<string> PreviewMainSelectedWidgetIDs
        {
            get { return previewMainSelectedWidgetIDs; }
        }

        private WidgetStyle ellipseStyle = new WidgetStyle(typeof(Widgets.EllipseWidget).Name);

        public WidgetStyle EllipseStyle
        {
            get { return ellipseStyle; }
            set
            {
                ellipseStyle = value;
                if (this.xmlDocument != null && this.xmlDocument.DocumentElement != null)
                {
                    this.xmlDocument.DocumentElement.SetAttribute(XmlTags.EllipseStyleTag, value.ToString());
                }
            }
        }

        private WidgetStyle rectangleStyle = new WidgetStyle(typeof(Widgets.RectangleWidget).Name);

        public WidgetStyle RectangleStyle
        {
            get { return rectangleStyle; }
            set
            {
                rectangleStyle = value;
                if (this.xmlDocument != null && this.xmlDocument.DocumentElement != null)
                {
                    this.xmlDocument.DocumentElement.SetAttribute(XmlTags.RectangleStyleTag, value.ToString());
                }
            }
        }

        private WidgetStyle rhombStyle = new WidgetStyle(typeof(Widgets.RhombWidget).Name);

        public WidgetStyle RhombStyle
        {
            get { return rhombStyle; }
            set
            {
                rhombStyle = value;
                if (this.xmlDocument != null && this.xmlDocument.DocumentElement != null)
                {
                    this.xmlDocument.DocumentElement.SetAttribute(XmlTags.RhombStyleTag, value.ToString());
                }
            }
        }

        private WidgetStyle triangleStyle = new WidgetStyle(typeof(Widgets.TriangleWidget).Name);

        public WidgetStyle TriangleStyle
        {
            get { return triangleStyle; }
            set
            {
                triangleStyle = value;
                if (this.xmlDocument != null && this.xmlDocument.DocumentElement != null)
                {
                    this.xmlDocument.DocumentElement.SetAttribute(XmlTags.TriangleStyleTag, value.ToString());
                }
            }
        }

        private WidgetStyle bracketStyle = new WidgetStyle(typeof(Widgets.BracketWidget).Name);

        public WidgetStyle BracketStyle
        {
            get { return bracketStyle; }
            set
            {
                bracketStyle = value;
                if (this.xmlDocument != null && this.xmlDocument.DocumentElement != null)
                {
                    this.xmlDocument.DocumentElement.SetAttribute(XmlTags.BracketStyleTag, value.ToString());
                }
            }
        }

        #endregion

        #region 方法=========================================================================================================

        /// <summary>
        /// 将指定的pageEditor添加到此类的mainStackPanel中。
        /// </summary>
        /// <param name="pageEditor"></param>
        /// <returns>返回新添加的pageEditor的索引。</returns>
        public int AddPageEditor(PageEditor pageEditor)
        {
            if (pageEditor == null) return -1;
            int result = this.mainStackPanel.Children.Add(pageEditor);

            pageEditor.RefreshPagination(string.Format("第 {0} 页，共 {1} 页",
                this.mainStackPanel.Children.Count - 1,
                this.mainStackPanel.Children.Count));

            return result;
        }

        /// <summary>
        /// 根据后台XmlDocument重新生成所有页面编辑器。
        /// 
        /// ★此方法不会修改IsModified属性的值。
        /// </summary>
        public void Build()
        {
            this.OnDocumentClosed(this, new EventArgs());

            this.mainStackPanel.Children.Clear();

            //初始化默认值。已移动到对应部分。2012年5月24日
            //this.defaultFontSize = 12;
            //this.defaultBackground = BrushManager.DefaultImageBrush;
            //this.defaultBackTileMode = TileMode.FlipXY;
            //this.defaultBackgroundText = "sTransparent";

            if (this.xmlDocument.DocumentElement == null) return;

            System.Xml.XmlAttribute attrDefaultFontSize =
                this.XmlDocument.DocumentElement.GetAttributeByName(XmlTags.DefaultFontSizeTag);
            if (attrDefaultFontSize != null)
            {
                this.defaultFontSize = double.Parse(attrDefaultFontSize.Value);
            }
            else
            {
                this.defaultFontSize = 12;
            }

            //2012年6月14日。已废弃。与部件本身相关的，改由“部件样式”决定。
            //System.Xml.XmlAttribute attrDefaultForeground =
            //    this.XmlDocument.DocumentElement.GetAttributeByName(XmlTags.DefaultForegroundTag);
            //if (attrDefaultForeground != null)
            //{
            //    this.defaultForeground = BrushManager.GetBrushByEnglishName(attrDefaultForeground.Value);
            //    this.RefreshDefaultForeground();
            //}
            //else
            //{
            //    this.defaultForeground = Brushes.Black;
            //}

            System.Xml.XmlAttribute attrDefaultBackTileMode =
                            this.xmlDocument.DocumentElement.GetAttributeByName(XmlTags.DefaultBackTileModeTag);
            if (attrDefaultBackTileMode != null && attrDefaultBackTileMode.Value != null &&
                attrDefaultBackTileMode.Value.Length > 0)
            {
                this.defaultBackTileMode = (TileMode)Enum.Parse(typeof(TileMode), attrDefaultBackTileMode.Value);
            }
            else
            {
                this.defaultBackTileMode = TileMode.FlipXY;
            }

            System.Xml.XmlAttribute attrDefaultBackground =
                this.XmlDocument.DocumentElement.GetAttributeByName(XmlTags.DocumentBackgroundTag);
            if (attrDefaultBackground != null)
            {
                this.documentBackground = BrushManager.Parse(attrDefaultBackground.Value);
                ImageBrush iBsh = this.documentBackground as ImageBrush;
                if (iBsh != null)
                {
                    iBsh.TileMode = this.defaultBackTileMode;
                }

                this.documentBackgroundText = attrDefaultBackground.Value;
            }
            else
            {
                this.documentBackground = Brushes.White;   //BrushManager.DefaultImageBrush;
                this.documentBackgroundText = "White";     //"sTransparent";
            }

            //读取线型部件控制点色彩。
            System.Xml.XmlAttribute attrWidgetStartCtrlBrush =
                this.XmlDocument.DocumentElement.GetAttributeByName(XmlTags.WidgetStartControlerBrush);
            if (attrWidgetStartCtrlBrush != null)
            {
                this.widgetStartControlerBrush = BrushManager.GetBrushByEnglishName(attrWidgetStartCtrlBrush.Value);
            }
            else
            {
                this.widgetStartControlerBrush = Brushes.Red;
            }

            System.Xml.XmlAttribute attrWidgetCenterCtrlBrush =
                this.XmlDocument.DocumentElement.GetAttributeByName(XmlTags.WidgetCenterControlerBrush);
            if (attrWidgetCenterCtrlBrush != null)
            {
                this.widgetCenterControlerBrush = BrushManager.GetBrushByEnglishName(attrWidgetCenterCtrlBrush.Value);
            }
            else
            {
                this.widgetCenterControlerBrush = Brushes.Yellow;
            }

            System.Xml.XmlAttribute attrWidgetEndCtrlBrush =
                this.XmlDocument.DocumentElement.GetAttributeByName(XmlTags.WidgetEndControlerBrush);
            if (attrWidgetEndCtrlBrush != null)
            {
                this.widgetEndControlerBrush = BrushManager.GetBrushByEnglishName(attrWidgetEndCtrlBrush.Value);
            }
            else
            {
                this.widgetEndControlerBrush = Brushes.Blue;
            }

            //读取选择框的色彩。
            System.Xml.XmlAttribute attrWidgetSelectionAdornerBrush =
                this.XmlDocument.DocumentElement.GetAttributeByName(XmlTags.WidgetSelectionAdornerBrush);
            if (attrWidgetSelectionAdornerBrush != null)
            {
                this.widgetSelectionAdornerBrush = BrushManager.GetBrushByEnglishName(attrWidgetSelectionAdornerBrush.Value);
            }
            else
            {
                this.widgetSelectionAdornerBrush = Brushes.Blue;
            }

            System.Xml.XmlAttribute attrPageFooter =
                this.xmlDocument.DocumentElement.GetAttributeByName(XmlTags.PageFooterTag);
            if (attrPageFooter != null)
            {
                this.pageFooter = attrPageFooter.Value;
            }
            else
            {
                this.pageFooter = string.Empty;//否则打开新的无页脚文档后会有残留。
            }

            System.Xml.XmlAttribute attrPageHeader =
                this.xmlDocument.DocumentElement.GetAttributeByName(XmlTags.PageHeaderTag);
            if (attrPageHeader != null)
            {
                this.pageHeader = attrPageHeader.Value;
            }
            else
            {
                this.pageHeader = string.Empty;//否则打开新的无页眉文档后会有残留。
            }

            System.Xml.XmlAttribute attrShowPageNumber 
                = this.xmlDocument.DocumentElement.GetAttributeByName(XmlTags.IsShowPageNumberTag);
            if(attrShowPageNumber != null)
            {
                if(bool.TryParse(attrShowPageNumber.Value,out bool isShowPageNumber))
                {
                    this.isShowPageNumber = isShowPageNumber;
                }
                else
                {
                    this.isShowPageNumber = true;
                }
            }
            else
            {
                this.isShowPageNumber = true;
            }

            //System.Xml.XmlAttribute attrAssistGridForm =
            //    this.xmlDocument.DocumentElement.GetAttributeByName(XmlTags.AssistGridFormTag);
            //if (attrAssistGridForm != null)
            //{
            //    this.assistGridForm = (AssistGridForm)Enum.Parse(typeof(AssistGridForm), attrAssistGridForm.Value);
            //}
            //else
            //{
            //    this.assistGridForm = Controls.AssistGridForm.Box;
            //}

            //在生成各部件之前要先读取所有部件的默认样式（如果存在），
            //因为默认样式只对新添加的部件有效，因此顺序不重要。
            BuildAllWidgetDefaultStyles();

            PageEditor fstPage = this.FirstPageEditor;
            if (fstPage != null) fstPage.IsMainSelected = true;

            //最后再读取各页。
            XmlNode pageSetNode = this.xmlDocument.DocumentElement.SelectSingleNode(XmlTags.PageSetTag);

            if (pageSetNode == null) return;

            XmlNodeList pageNodeList = pageSetNode.SelectNodes(XmlTags.PageTag);

            if (pageNodeList == null || pageNodeList.Count <= 0) return;

            foreach (XmlNode pageNode in pageNodeList)
            {
                PageEditor pageEditor = new PageEditor(this);
                pageEditor.XmlData = pageNode;

                this.mainStackPanel.Children.Add(pageEditor);

                //刷新各部件尺寸、位置，以防出错（例如“组”的尺寸就会出错。
                pageEditor.RefreshWidgetsLocation();
            }

            //跳到开头。
            if (masterWindow != null && masterWindow.MainScrollViewer.Content == this)
            {
                if (this.Children.Count > 0)
                {
                    PageEditor fstPe = this.Children[0] as PageEditor;
                    if (fstPe != null)
                    {
                        this.TryToDisplayPageEditor(fstPe, false);
                    }
                }
            }

            this.RefreshWidgetSelectionAdornerBrush();
            this.RefreshDefaultFontSize();
            this.RefreshDocumentBackground();
            this.RefreshPageFooter();
            this.RefreshPageFooterLocation();
            this.RefreshPageHeader();
            //this.RefreshAssistGridForm();

            //重建文档后，刷新各页页号。
            this.RefreshPaginations();

            //打开文档后，刷新自动编号。
            this.RefreshAutoNumberStrings();

            //打开文档后，刷新所有内容部件的链接页提示信息。
            this.RefreshContentWidgetsLinkToolTip();

            this.OnDocumentOpened(this, new EventArgs());
        }

        /// <summary>
        /// 读取可能存在的所有部件的默认样式。
        /// </summary>
        private void BuildAllWidgetDefaultStyles()
        {
            if (this.xmlDocument == null || this.XmlDocument.DocumentElement == null)
            {
                this.textAreaStyle = this.GetInitilizedWidgetStyle(typeof(Widgets.TextArea).Name);
                this.pictureBoxStyle = this.GetInitilizedWidgetStyle(typeof(Widgets.PictureBox).Name);
                this.groupStyle = this.GetInitilizedWidgetStyle(typeof(Widgets.GroupWidget).Name);

                this.straitLineStyle = this.GetInitilizedWidgetStyle(typeof(Widgets.StraitLineWidget).Name);
                this.bezierLineStyle = this.GetInitilizedWidgetStyle(typeof(Widgets.BezierLineWidget).Name);
                this.polyLineStyle = this.GetInitilizedWidgetStyle(typeof(Widgets.PolyLineWidget).Name);
                this.bracketStyle = this.GetInitilizedWidgetStyle(typeof(Widgets.BracketWidget).Name);

                this.ellipseStyle = this.GetInitilizedWidgetStyle(typeof(Widgets.EllipseWidget).Name);
                this.rectangleStyle = this.GetInitilizedWidgetStyle(typeof(Widgets.RectangleWidget).Name);
                this.rhombStyle = this.GetInitilizedWidgetStyle(typeof(Widgets.RhombWidget).Name);
                this.triangleStyle = this.GetInitilizedWidgetStyle(typeof(Widgets.TriangleWidget).Name);
                return;
            }

            System.Xml.XmlAttribute attrTextAreaStyle =
                this.XmlDocument.DocumentElement.GetAttributeByName(XmlTags.TextAreaStyleTag);
            if (attrTextAreaStyle != null)
            {
                this.textAreaStyle = WidgetStyle.FromString(attrTextAreaStyle.Value);
            }
            else
            {
                this.textAreaStyle = this.GetInitilizedWidgetStyle(typeof(Widgets.TextArea).Name);
            }

            System.Xml.XmlAttribute attrPictureBoxStyle =
                this.XmlDocument.DocumentElement.GetAttributeByName(XmlTags.PictureBoxStyleTag);
            if (attrPictureBoxStyle != null)
            {
                this.pictureBoxStyle = WidgetStyle.FromString(attrPictureBoxStyle.Value);
            }
            else
            {
                this.pictureBoxStyle = this.GetInitilizedWidgetStyle(typeof(Widgets.PictureBox).Name);
            }

            System.Xml.XmlAttribute attrGroupStyle =
                this.XmlDocument.DocumentElement.GetAttributeByName(XmlTags.GroupStyleTag);
            if (attrGroupStyle != null)
            {
                this.groupStyle = WidgetStyle.FromString(attrGroupStyle.Value);
            }
            else
            {
                this.groupStyle = this.GetInitilizedWidgetStyle(typeof(Widgets.GroupWidget).Name);
            }

            System.Xml.XmlAttribute attrStraitLineStyle =
                this.XmlDocument.DocumentElement.GetAttributeByName(XmlTags.StraitLineStyleTag);
            if (attrStraitLineStyle != null)
            {
                this.straitLineStyle = WidgetStyle.FromString(attrStraitLineStyle.Value);
            }
            else
            {
                this.straitLineStyle = this.GetInitilizedWidgetStyle(typeof(Widgets.StraitLineWidget).Name);
            }

            System.Xml.XmlAttribute attrBezierLineStyle =
                this.XmlDocument.DocumentElement.GetAttributeByName(XmlTags.BezierLineStyleTag);
            if (attrBezierLineStyle != null)
            {
                this.bezierLineStyle = WidgetStyle.FromString(attrBezierLineStyle.Value);
            }
            else
            {
                this.bezierLineStyle = this.GetInitilizedWidgetStyle(typeof(Widgets.BezierLineWidget).Name);
            }

            System.Xml.XmlAttribute attrPolyLineStyle =
                this.XmlDocument.DocumentElement.GetAttributeByName(XmlTags.PolyLineStyleTag);
            if (attrPolyLineStyle != null)
            {
                this.polyLineStyle = WidgetStyle.FromString(attrPolyLineStyle.Value);
            }
            else
            {
                this.polyLineStyle = this.GetInitilizedWidgetStyle(typeof(Widgets.PolyLineWidget).Name);
            }

            System.Xml.XmlAttribute attrRectangleStyle =
                this.XmlDocument.DocumentElement.GetAttributeByName(XmlTags.RectangleStyleTag);
            if (attrRectangleStyle != null)
            {
                this.rectangleStyle = WidgetStyle.FromString(attrRectangleStyle.Value);
            }
            else
            {
                this.rectangleStyle = this.GetInitilizedWidgetStyle(typeof(Widgets.RectangleWidget).Name);
            }

            System.Xml.XmlAttribute attrEllipseStyle =
                this.XmlDocument.DocumentElement.GetAttributeByName(XmlTags.EllipseStyleTag);
            if (attrEllipseStyle != null)
            {
                this.ellipseStyle = WidgetStyle.FromString(attrEllipseStyle.Value);
            }
            else
            {
                this.ellipseStyle = this.GetInitilizedWidgetStyle(typeof(Widgets.EllipseWidget).Name);
            }

            System.Xml.XmlAttribute attrRhombStyle =
                this.XmlDocument.DocumentElement.GetAttributeByName(XmlTags.RhombStyleTag);
            if (attrRhombStyle != null)
            {
                this.rhombStyle = WidgetStyle.FromString(attrRhombStyle.Value);
            }
            else
            {
                this.rhombStyle = this.GetInitilizedWidgetStyle(typeof(Widgets.RhombWidget).Name);
            }

            System.Xml.XmlAttribute attrTriangleStyle =
                this.XmlDocument.DocumentElement.GetAttributeByName(XmlTags.TriangleStyleTag);
            if (attrTriangleStyle != null)
            {
                this.triangleStyle = WidgetStyle.FromString(attrTriangleStyle.Value);
            }
            else
            {
                this.triangleStyle = this.GetInitilizedWidgetStyle(typeof(Widgets.TriangleWidget).Name);
            }

            System.Xml.XmlAttribute attrBracketStyle =
                this.XmlDocument.DocumentElement.GetAttributeByName(XmlTags.BracketStyleTag);
            if (attrBracketStyle != null)
            {
                this.bracketStyle = WidgetStyle.FromString(attrBracketStyle.Value);
            }
            else
            {
                this.bracketStyle = this.GetInitilizedWidgetStyle(typeof(Widgets.BracketWidget).Name);
            }

            //注意，这里用字段而不是用属性。因为不需要写Xml数据。
            //另，部件样式只对将要添加的部件有效，因此不需要刷新效果。
        }

        public void ClearWidgetsSelection()
        {
            List<Widget> selectedWidgetsList = this.GetSelectedWidgetsList();
            foreach (Widget w in selectedWidgetsList)
            {
                w.IsSelected = false;
            }
        }

        private void BuildAssistLineBrushes()
        {
            #region 第一种：网格式[50×50]

            this.assistGridLinesBrush = new DrawingBrush();
            this.assistGridLinesBrush.Stretch = Stretch.None;
            this.assistGridLinesBrush.TileMode = TileMode.Tile;
            //this.gridLinesBrush.Viewbox =
            this.assistGridLinesBrush.Viewport = new Rect(1, 1, 50, 50);
            //this.gridLinesBrush.ViewboxUnits =
            this.assistGridLinesBrush.ViewportUnits = BrushMappingMode.Absolute;

            DrawingGroup drawingGroup = new DrawingGroup();
            drawingGroup.GuidelineSet = new GuidelineSet();
            drawingGroup.GuidelineSet.GuidelinesX = new DoubleCollection() { 0, 10, 20, 30, 40, 50 };
            drawingGroup.GuidelineSet.GuidelinesY = new DoubleCollection() { 0, 10, 20, 30, 40, 50 };

            Pen penA = new Pen(this.WidgetSelectionAdornerBrush, 0.1);
            penA.DashStyle = new DashStyle(new DoubleCollection() { 2, 2, }, 4);

            Pen penB = new Pen(this.WidgetSelectionAdornerBrush, 0.8);
            penB.DashStyle = new DashStyle(new DoubleCollection() { 3, 3 }, 2);

            GeometryDrawing gdHA = new GeometryDrawing() { Pen = penA };
            LineGeometry lgHA = new LineGeometry()
            {
                StartPoint = new Point(0, 10),
                EndPoint = new Point(50, 10)
            };
            gdHA.Geometry = lgHA; drawingGroup.Children.Add(gdHA);

            GeometryDrawing gdHB = new GeometryDrawing() { Pen = penA };
            LineGeometry lgHB = new LineGeometry()
            {
                StartPoint = new Point(0, 20),
                EndPoint = new Point(50, 20)
            };
            gdHB.Geometry = lgHB; drawingGroup.Children.Add(gdHB);

            GeometryDrawing gdHC = new GeometryDrawing() { Pen = penA };
            LineGeometry lgHC = new LineGeometry()
            {
                StartPoint = new Point(0, 30),
                EndPoint = new Point(50, 30)
            };
            gdHC.Geometry = lgHC; drawingGroup.Children.Add(gdHC);

            GeometryDrawing gdHD = new GeometryDrawing() { Pen = penA };
            LineGeometry lgHD = new LineGeometry()
            {
                StartPoint = new Point(0, 40),
                EndPoint = new Point(50, 40)
            };
            gdHD.Geometry = lgHD; drawingGroup.Children.Add(gdHD);

            GeometryDrawing gdHE = new GeometryDrawing() { Pen = penB };
            LineGeometry lgHE = new LineGeometry()
            {
                StartPoint = new Point(0, 50),
                EndPoint = new Point(50, 50)
            };
            gdHE.Geometry = lgHE; drawingGroup.Children.Add(gdHE);

            GeometryDrawing gdVA = new GeometryDrawing() { Pen = penA };
            LineGeometry lgVA = new LineGeometry()
            {
                StartPoint = new Point(10, 0),
                EndPoint = new Point(10, 50)
            };
            gdVA.Geometry = lgVA; drawingGroup.Children.Add(gdVA);

            GeometryDrawing gdVB = new GeometryDrawing() { Pen = penA };
            LineGeometry lgVB = new LineGeometry()
            {
                StartPoint = new Point(20, 0),
                EndPoint = new Point(20, 50)
            };
            gdVB.Geometry = lgVB; drawingGroup.Children.Add(gdVB);

            GeometryDrawing gdVC = new GeometryDrawing() { Pen = penA };
            LineGeometry lgVC = new LineGeometry()
            {
                StartPoint = new Point(30, 0),
                EndPoint = new Point(30, 50)
            };
            gdVC.Geometry = lgVC; drawingGroup.Children.Add(gdVC);

            GeometryDrawing gdVD = new GeometryDrawing() { Pen = penA };
            LineGeometry lgVD = new LineGeometry()
            {
                StartPoint = new Point(40, 0),
                EndPoint = new Point(40, 50)
            };
            gdVD.Geometry = lgVD; drawingGroup.Children.Add(gdVD);

            GeometryDrawing gdVE = new GeometryDrawing() { Pen = penB };
            LineGeometry lgVE = new LineGeometry()
            {
                StartPoint = new Point(50, 0),
                EndPoint = new Point(50, 50)
            };
            gdVE.Geometry = lgVE; drawingGroup.Children.Add(gdVE);

            this.assistGridLinesBrush.Drawing = drawingGroup;

            #endregion

            #region 第二种：田字格式[50×50]

            this.assistTianziLinesBrush = new DrawingBrush();
            this.assistTianziLinesBrush.Stretch = Stretch.None;
            this.assistTianziLinesBrush.TileMode = TileMode.Tile;
            //this.gridLinesBrush.Viewbox =
            this.assistTianziLinesBrush.Viewport = new Rect(1, 1, 50, 50);
            //this.gridLinesBrush.ViewboxUnits =
            this.assistTianziLinesBrush.ViewportUnits = BrushMappingMode.Absolute;

            DrawingGroup tianziDrawingGroup = new DrawingGroup();
            tianziDrawingGroup.GuidelineSet = new GuidelineSet();
            tianziDrawingGroup.GuidelineSet.GuidelinesX = new DoubleCollection() { 0, 24, 49, 50 };
            tianziDrawingGroup.GuidelineSet.GuidelinesY = new DoubleCollection() { 0, 24, 49, 50 };

            GeometryDrawing tianziGdHA = new GeometryDrawing() { Pen = penA };
            LineGeometry tianziLgHA = new LineGeometry()
            {
                StartPoint = new Point(0, 24),
                EndPoint = new Point(50, 24)
            };
            tianziGdHA.Geometry = tianziLgHA; tianziDrawingGroup.Children.Add(tianziGdHA);

            //GeometryDrawing tianziGdHB = new GeometryDrawing() { Pen = penA };
            //LineGeometry tianziLgHB = new LineGeometry()
            //{
            //    StartPoint = new Point(0, 0),
            //    EndPoint = new Point(49, 49)
            //};
            //tianziGdHB.Geometry = tianziLgHB; tianziDrawingGroup.Children.Add(tianziGdHB);

            GeometryDrawing tianziGdHE = new GeometryDrawing() { Pen = penB };
            LineGeometry tianziLgHE = new LineGeometry()
            {
                StartPoint = new Point(0, 50),
                EndPoint = new Point(50, 50)
            };
            tianziGdHE.Geometry = tianziLgHE; tianziDrawingGroup.Children.Add(tianziGdHE);

            GeometryDrawing tianziGdVA = new GeometryDrawing() { Pen = penA };
            LineGeometry tianziLgVA = new LineGeometry()
            {
                StartPoint = new Point(24, 0),
                EndPoint = new Point(24, 50)
            };
            tianziGdVA.Geometry = tianziLgVA; tianziDrawingGroup.Children.Add(tianziGdVA);

            //GeometryDrawing tianziGdVB = new GeometryDrawing() { Pen = penA };
            //LineGeometry tianziLgVB = new LineGeometry()
            //{
            //    StartPoint = new Point(49, 0),
            //    EndPoint = new Point(0, 49)
            //};
            //tianziGdVB.Geometry = tianziLgVB; tianziDrawingGroup.Children.Add(tianziGdVB);

            GeometryDrawing tianziGdVE = new GeometryDrawing() { Pen = penB };
            LineGeometry tianziLgVE = new LineGeometry()
            {
                StartPoint = new Point(50, 0),
                EndPoint = new Point(50, 50)
            };
            tianziGdVE.Geometry = tianziLgVE; tianziDrawingGroup.Children.Add(tianziGdVE);

            this.assistTianziLinesBrush.Drawing = tianziDrawingGroup;

            #endregion

            #region 第三种：米字格式[50×50]

            this.assistMiziLinesBrush = new DrawingBrush();
            this.assistMiziLinesBrush.Stretch = Stretch.None;
            this.assistMiziLinesBrush.TileMode = TileMode.Tile;
            //this.gridLinesBrush.Viewbox =
            this.assistMiziLinesBrush.Viewport = new Rect(1, 1, 50, 50);
            //this.gridLinesBrush.ViewboxUnits =
            this.assistMiziLinesBrush.ViewportUnits = BrushMappingMode.Absolute;

            DrawingGroup miziDrawingGroup = new DrawingGroup();
            miziDrawingGroup.GuidelineSet = new GuidelineSet();
            miziDrawingGroup.GuidelineSet.GuidelinesX = new DoubleCollection() { 0, 24, 49, 50 };
            miziDrawingGroup.GuidelineSet.GuidelinesY = new DoubleCollection() { 0, 24, 49, 50 };

            GeometryDrawing miziGdHA = new GeometryDrawing() { Pen = penA };
            LineGeometry miziLgHA = new LineGeometry()
            {
                StartPoint = new Point(0, 24),
                EndPoint = new Point(50, 24)
            };
            miziGdHA.Geometry = miziLgHA; miziDrawingGroup.Children.Add(miziGdHA);

            GeometryDrawing miziGdHB = new GeometryDrawing() { Pen = penA };
            LineGeometry miziLgHB = new LineGeometry()
            {
                StartPoint = new Point(0, 0),
                EndPoint = new Point(49, 49)
            };
            miziGdHB.Geometry = miziLgHB; miziDrawingGroup.Children.Add(miziGdHB);

            GeometryDrawing miziGdHE = new GeometryDrawing() { Pen = penB };
            LineGeometry miziLgHE = new LineGeometry()
            {
                StartPoint = new Point(0, 50),
                EndPoint = new Point(50, 50)
            };
            miziGdHE.Geometry = miziLgHE; miziDrawingGroup.Children.Add(miziGdHE);

            GeometryDrawing miziGdVA = new GeometryDrawing() { Pen = penA };
            LineGeometry miziLgVA = new LineGeometry()
            {
                StartPoint = new Point(24, 0),
                EndPoint = new Point(24, 50)
            };
            miziGdVA.Geometry = miziLgVA; miziDrawingGroup.Children.Add(miziGdVA);

            GeometryDrawing miziGdVB = new GeometryDrawing() { Pen = penA };
            LineGeometry miziLgVB = new LineGeometry()
            {
                StartPoint = new Point(49, 0),
                EndPoint = new Point(0, 49)
            };
            miziGdVB.Geometry = miziLgVB; miziDrawingGroup.Children.Add(miziGdVB);

            GeometryDrawing miziGdVE = new GeometryDrawing() { Pen = penB };
            LineGeometry miziLgVE = new LineGeometry()
            {
                StartPoint = new Point(50, 0),
                EndPoint = new Point(50, 50)
            };
            miziGdVE.Geometry = miziLgVE; miziDrawingGroup.Children.Add(miziGdVE);

            this.assistMiziLinesBrush.Drawing = miziDrawingGroup;

            #endregion

            #region 第四种：回宫格

            this.assistHuiziLinesBrush = new DrawingBrush();
            this.assistHuiziLinesBrush.Stretch = Stretch.None;
            this.assistHuiziLinesBrush.TileMode = TileMode.Tile;
            this.assistHuiziLinesBrush.Viewport = new Rect(1, 1, 50, 50);
            this.assistHuiziLinesBrush.ViewportUnits = BrushMappingMode.Absolute;

            DrawingGroup huiziDrawingGroup = new DrawingGroup();
            huiziDrawingGroup.GuidelineSet = new GuidelineSet();
            huiziDrawingGroup.GuidelineSet.GuidelinesX = new DoubleCollection() { 0, 6, 13, 35, 43, 50 };
            huiziDrawingGroup.GuidelineSet.GuidelinesY = new DoubleCollection() { 0, 6, 13, 35, 43, 50 };

            GeometryDrawing huiziGdHE = new GeometryDrawing() { Pen = penB };
            LineGeometry huiziLgHE = new LineGeometry()
            {
                StartPoint = new Point(0, 50),
                EndPoint = new Point(50, 50)
            };
            huiziGdHE.Geometry = huiziLgHE; huiziDrawingGroup.Children.Add(huiziGdHE);

            GeometryDrawing huiziGdHB = new GeometryDrawing() { Pen = penA };
            LineGeometry huiziLgHB = new LineGeometry()
            {
                StartPoint = new Point(13, 6),
                EndPoint = new Point(35, 6)
            };
            huiziGdHB.Geometry = huiziLgHB; huiziDrawingGroup.Children.Add(huiziGdHB);

            GeometryDrawing huiziGdHC = new GeometryDrawing() { Pen = penA };
            LineGeometry huiziLgHC = new LineGeometry()
            {
                StartPoint = new Point(13, 42),
                EndPoint = new Point(35, 42)
            };
            huiziGdHC.Geometry = huiziLgHC; huiziDrawingGroup.Children.Add(huiziGdHC);

            GeometryDrawing huiziGdVE = new GeometryDrawing() { Pen = penB };
            LineGeometry huiziLgVE = new LineGeometry()
            {
                StartPoint = new Point(50, 0),
                EndPoint = new Point(50, 50)
            };
            huiziGdVE.Geometry = huiziLgVE; huiziDrawingGroup.Children.Add(huiziGdVE);

            GeometryDrawing huiziGdVB = new GeometryDrawing() { Pen = penA };
            LineGeometry huiziLgVB = new LineGeometry()
            {
                StartPoint = new Point(13, 6),
                EndPoint = new Point(13, 42)
            };
            huiziGdVB.Geometry = huiziLgVB; huiziDrawingGroup.Children.Add(huiziGdVB);

            GeometryDrawing huiziGdVC = new GeometryDrawing() { Pen = penA };
            LineGeometry huiziLgVC = new LineGeometry()
            {
                StartPoint = new Point(35, 6),
                EndPoint = new Point(35, 42)
            };
            huiziGdVC.Geometry = huiziLgVC; huiziDrawingGroup.Children.Add(huiziGdVC);

            this.assistHuiziLinesBrush.Drawing = huiziDrawingGroup;

            #endregion
        }

        /// <summary>
        /// 关闭文档。清除所有部件。清除所有配置。清除后台Xml。
        /// </summary>
        public void CloseDocument()
        {
            this.xmlDocument.RemoveAll();
            this.Build();

            //重置各属性。
            this.defaultFontSize = 12;
            this.defaultBackTileMode = TileMode.FlipXY;
            this.documentBackground = BrushManager.DefaultImageBrush;
            this.formatBrush = null;

            this.FullPathOfDiskFile = null;//这用属性，以更改主窗口标题。

            this.mouseDraggingType = Enums.PageDraggingType.None;
            this.orientation = System.Windows.Controls.Orientation.Vertical;
            this.pageFooter =
            this.pageHeader = string.Empty;
            this.replaceBox = null;
            this.widgetCenterControlerBrush = Brushes.Yellow;
            this.widgetEndControlerBrush = Brushes.Blue;
            this.widgetSelectionAdornerBrush = Brushes.Blue;
            this.widgetStartControlerBrush = Brushes.Red;

            //重置缩放比例
            if (masterWindow != null)
            {
                masterWindow.SliderOfScale.Value = 0;
            }

            //重置各部件样式。
            this.BuildAllWidgetDefaultStyles();//xmlDocument为null时自动重置。

            //重置撤销列表。
            this.modifingItemsList.Reset();
            //this.isModified = false;          //在Reset()方法中已调用。
            //this.modifingItemsList.Clear();   //在Reset()方法中已调用。
        }

        /// <summary>
        /// 返回是否包含指定编辑器（pageEditor）。
        /// 如果pageEditor为null，会返回false而不会抛出异常。
        /// </summary>
        /// <param name="pageEditor">要寻找的pageEditor。</param>
        /// <returns></returns>
        public bool Contains(PageEditor pageEditor)
        {
            if (pageEditor == null) return false;

            return this.mainStackPanel.Children.Contains(pageEditor);
        }

        /// <summary>
        /// 取所有页面列表。
        /// </summary>
        /// <returns>如果没有页面，返回空列表而不是null值。</returns>
        public List<PageEditor> GetAllPageEditors()
        {
            List<PageEditor> pageList = new List<PageEditor>();
            foreach (UIElement ue in this.mainStackPanel.Children)
            {
                PageEditor pe = ue as PageEditor;
                if (pe != null)
                {
                    pageList.Add(pe);
                }
            }

            return pageList;
        }

        /// <summary>
        /// 根据ID找出PageEditor。
        /// </summary>
        /// <param name="id">要找的PageEditor的ID。</param>
        /// <returns>如果找不到，会返回null。</returns>
        public PageEditor GetPageEditor(string id)
        {
            foreach (UIElement ue in this.mainStackPanel.Children)
            {
                PageEditor pe = ue as PageEditor;
                if (pe == null) continue;

                if (pe.Id == id) return pe;
            }

            return null;
        }

        /// <summary>
        /// 根据整个文档生成图片数据。
        /// </summary>
        /// <param name="highQuality">是否按照较高的DPI导出（用于打印的图像应使用此值）。
        /// 为True时使用300DPI，为False时使用96DPI。</param>
        public RenderTargetBitmap GetRenderTargetBitmap(bool highQuality = true)
        {
            RenderTargetBitmap rtb;
            double scale = ScaleValueConverter.GetNewScaleValue(Globals.MainWindow.SliderOfScale.Value);

            if (highQuality)
            {
                rtb = new RenderTargetBitmap(
                    (int)(this.mainStackPanel.ActualWidth * 3.125 * scale + 1),
                    (int)(this.mainStackPanel.ActualHeight * 3.125 * scale + 1),
                    300, 300, PixelFormats.Pbgra32);//300÷96=3.125//用来打印的图片分辨率要高些。96DPI只适合屏幕显示。
            }
            else
            {
                rtb = new RenderTargetBitmap(
                    (int)(this.mainStackPanel.ActualWidth * scale),
                    (int)(this.mainStackPanel.ActualHeight * scale),
                    96, 96, PixelFormats.Pbgra32);//只在屏幕上显示的图片分辨率可以低些，96DPI就够了。
            }

            rtb.Render(this.mainStackPanel);
            return rtb;
        }

        /// <summary>
        /// 某些操作不需要更改页面的选定状态。此时可直接传入info给此方法。
        /// </summary>
        /// <param name="info">需要记录页面选定状态的ModifingInfo实例。</param>
        public void GetSelectedPageEditorStatus(ModifingInfo info)
        {
            if (info == null) return;

            List<PageEditor> selectedPageEditors = this.GetSelectedPageEditorsList();
            foreach (PageEditor pe in selectedPageEditors)
            {
                info.AddPageEditorID_NewSelected(pe.Id);
                info.AddPageEditorID_OldSelected(pe.Id);
                if (pe.IsMainSelected)
                {
                    info.NewMainSelectedPageEditorID = pe.Id;
                    info.OldMainSelectedPageEditorID = pe.Id;
                }
            }
        }

        /// <summary>
        /// 记录所有“被选定”部件的选定状态，以备重做后恢复部件选定。此时可直接传入info给此方法。
        /// </summary>
        /// <param name="info">需要记录部件选定状态的ModifingInfo实例。</param>
        public void GetSelectedWidgetStatus_New(ModifingInfo info)
        {
            if (info == null) return;

            List<Widgets.Widget> selectedWidgets = this.GetSelectedWidgetsList();
            foreach (Widgets.Widget w in selectedWidgets)
            {
                info.AddWidgetID_NewSelected(w.Id);
                if (w.IsMainSelected)
                {
                    info.NewMainSelectedWidgetID = w.Id;
                }
            }
        }

        /// <summary>
        /// 记录所有“被选定”部件的选定状态，以备撤销后恢复部件选定。此时可直接传入info给此方法。
        /// </summary>
        /// <param name="info">需要记录部件选定状态的ModifingInfo实例。</param>
        public void GetSelectedWidgetStatus_Old(ModifingInfo info)
        {
            if (info == null) return;

            List<Widgets.Widget> selectedWidgets = this.GetSelectedWidgetsList();
            foreach (Widgets.Widget w in selectedWidgets)
            {
                info.AddWidgetID_OldSelected(w.Id);
                if (w.IsMainSelected)
                {
                    info.OldMainSelectedWidgetID = w.Id;
                }
            }
        }

        /// <summary>
        /// 取所有页面的所有部件。
        /// </summary>
        /// <returns>不会返回null。而是返回空列表。</returns>
        public List<Widgets.Widget> GetListOfAllWidgets()
        {
            List<Widgets.Widget> allWidgetList = new List<Widgets.Widget>();

            foreach (UIElement pue in this.mainStackPanel.Children)
            {
                PageEditor pe = pue as PageEditor;
                if (pe == null) continue;

                List<Widgets.Widget> peWidgetList = pe.GetListOfAllWidgets();

                allWidgetList.AddRange(peWidgetList);
            }

            return allWidgetList;
        }

        /// <summary>
        /// 返回selectedPageEditor列表中找到的第一个处于“IsMainSelected”状态的PageEditor。
        /// 
        /// ★如果所有PageEditor都没有处于这一状态，返回null。
        /// </summary>
        /// <returns>如果没有，返回null。</returns>
        public PageEditor GetMainSelectedPageEditor()
        {
            foreach (UIElement ue in this.mainStackPanel.Children)
            {
                PageEditor pe = ue as PageEditor;
                if (pe == null) continue;

                if (pe.IsMainSelected) return pe;
            }

            return null;
        }

        /// <summary>
        /// 返回selectedWidgets列表中找到的第一个处于“IsMainSelected”状态的PageEditor。
        /// 
        /// ★如果所有Widget都没有处于这一状态，返回null。
        /// </summary>
        /// <returns>如果没有，返回null。</returns>
        public Widgets.Widget GetMainSelectedWidget()
        {
            foreach (UIElement ueInEdotorManager in this.mainStackPanel.Children)
            {
                PageEditor pageEditor = ueInEdotorManager as PageEditor;
                if (pageEditor == null) continue;

                foreach (UIElement ue in pageEditor.Children)
                {
                    Widgets.Widget w = ue as Widgets.Widget;
                    if (w.IsMainSelected) return w;
                }
            }

            return null;
        }

        /// <summary>
        /// 取当前选定的页面的数目。
        /// </summary>
        /// <returns></returns>
        public int GetSelectedPageEditorCount()
        {
            int selPagesCount = 0;

            foreach (UIElement ue in this.mainStackPanel.Children)
            {
                PageEditor pe = ue as PageEditor;
                if (pe == null) continue;

                if (pe.IsSelected) selPagesCount++;
            }

            return selPagesCount;
        }

        /// <summary>
        /// 取当前编辑器管理器中所有处于“被选定”状态的PageEditor。
        /// </summary>
        /// <returns>无论如何，都会返回一个列表。不会返回null。</returns>
        public List<PageEditor> GetSelectedPageEditorsList()
        {
            List<PageEditor> selectedPageEditorList = new List<PageEditor>();

            foreach (UIElement ue in this.mainStackPanel.Children)
            {
                PageEditor pe = ue as PageEditor;
                if (pe == null) continue;

                if (pe.IsSelected) selectedPageEditorList.Add(pe);
            }

            return selectedPageEditorList;
        }

        /// <summary>
        /// 取选定的部件的数目（在全部页面编辑器中）。
        /// </summary>
        /// <returns>找不到就返回0。</returns>
        public int GetSelectedWidgetsCount()
        {
            int selWidgetsCount = 0;

            foreach (UIElement uePage in this.mainStackPanel.Children)
            {
                PageEditor pe = uePage as PageEditor;
                if (pe == null) continue;

                foreach (UIElement ueWidget in pe.Children)
                {
                    Widgets.Widget w = ueWidget as Widgets.Widget;

                    if (w.IsSelected) selWidgetsCount++;
                }
            }

            return selWidgetsCount;
        }

        /// <summary>
        /// 取当前选定的所有TextArea。
        /// </summary>
        /// <returns></returns>
        public List<Widgets.TextArea> GetSelectedTextAreaList()
        {
            List<Widgets.TextArea> selectedTextAreaList = new List<Widgets.TextArea>();

            foreach (UIElement uePage in this.mainStackPanel.Children)
            {
                PageEditor pe = uePage as PageEditor;
                if (pe == null) continue;

                foreach (UIElement ueWidget in pe.Children)
                {
                    Widgets.TextArea ta = ueWidget as Widgets.TextArea;

                    if (ta != null && ta.IsSelected) selectedTextAreaList.Add(ta);
                }
            }

            return selectedTextAreaList;
        }

        /// <summary>
        /// 取当前编辑器管理器中所有处于“被选定”状态的Widget。
        /// ——取值不受Widget所属的编辑器的影响（即使编辑器未处于被选定状态也会返回）。
        /// </summary>
        /// <returns>无论如何，都会返回一个列表。不会返回null。</returns>
        public List<Widgets.Widget> GetSelectedWidgetsList()
        {
            List<Widgets.Widget> selectedWidgetList = new List<Widgets.Widget>();

            foreach (UIElement uePage in this.mainStackPanel.Children)
            {
                PageEditor pe = uePage as PageEditor;
                if (pe == null) continue;

                foreach (UIElement ueWidget in pe.Children)
                {
                    Widgets.Widget w = ueWidget as Widgets.Widget;

                    if (w.IsSelected) selectedWidgetList.Add(w);
                }
            }

            return selectedWidgetList;
        }

        public Widget GetWidget(string widgetId)
        {
            if (string.IsNullOrEmpty(widgetId)) return null;

            if (this.mainStackPanel.Children.Count <= 0) return null;

            foreach (UIElement uePage in this.mainStackPanel.Children)
            {
                PageEditor pe = uePage as PageEditor;
                if (pe == null) continue;

                foreach (UIElement ueWidget in pe.Children)
                {
                    Widgets.Widget w = ueWidget as Widgets.Widget;

                    if (w.Id == widgetId) return w;
                }
            }

            return null;
        }

        /// <summary>
        /// 寻找指定的pageEditor的索引。如果找不到，会返回-1。
        /// </summary>
        /// <param name="pageEditor">要寻找的pageEditor。</param>
        /// <returns>返回pageEditor的索引。如果找不到，返回-1，不会抛出异常。</returns>
        public int IndexOf(PageEditor pageEditor)
        {
            if (pageEditor == null || this.mainStackPanel == null) return -1;

            if (this.mainStackPanel.Children.Contains(pageEditor) == false) return -1;

            return this.mainStackPanel.Children.IndexOf(pageEditor);
        }

        /// <summary>
        /// 初始化一个含有一个空白页面的空文档。
        /// </summary>
        public void InitilizeDocument()
        {
            this.xmlDocument.LoadXml(Properties.Resources.InitilizeXmlDocument);
            this.Build();
            this.ModifingItemsList.Reset();

            PageEditor firstPageEditor = this.FirstPageEditor;
            if (firstPageEditor != null)
            {
                firstPageEditor.IsMainSelected = true;
            }
        }

        /// <summary>
        /// 添加一个新PageEditor。
        /// </summary>
        /// <param name="basePageEditor">基准位置。newPageEditor将出现在basePageEditor之后。</param>
        /// <param name="newPageEditor">要添加的新PageEditor。</param>
        /// <returns>如果添加成功返回索引；否则返回-1。</returns>
        public int InsertAfter(PageEditor basePageEditor, PageEditor newPageEditor)
        {
            if (basePageEditor == null || newPageEditor == null ||
                this.mainStackPanel.Children.Contains(basePageEditor) == false)
                return -1;

            int baseIndex = this.mainStackPanel.Children.IndexOf(basePageEditor);
            int newIndex = baseIndex + 1;

            this.mainStackPanel.Children.Insert(newIndex, newPageEditor);
            return newIndex;
        }

        /// <summary>
        /// 在指定索引处添加一个新PageEditor。
        /// </summary>
        /// <param name="newIndex">要插入到的位置索引。</param>
        /// <param name="newPageEditor">要添加的新PageEditor。</param>
        public bool InsertAt(int newIndex, PageEditor newPageEditor)
        {
            if (newIndex < 0 || newIndex > this.mainStackPanel.Children.Count) return false;
            this.mainStackPanel.Children.Insert(newIndex, newPageEditor);
            return true;
        }

        /// <summary>
        /// 将PageEditor的MouseLeftButtonDroped事件挂接过来。
        /// 
        /// 注：此方法应由PageEditor的构造方法调用。
        /// </summary>
        /// <param name="pageEditor">要在本EditorManager内部。</param>
        public void LinkMouseEvents(PageEditor pageEditor)
        {
            pageEditor.MouseLeftButtonDroped +=
                new EventHandler<MouseLeftButtonDraggingEventArgs>(pageEditor_MouseLeftButtonDroped);
            pageEditor.WidgetControlerMoved +=
                new EventHandler<MouseLeftButtonDraggingEventArgs>(pageEditor_WidgetControlerMoved);
            pageEditor.WidgetsMoved += new EventHandler<MouseLeftButtonDraggingEventArgs>(pageEditor_WidgetsMoved);
            pageEditor.MainSelectedWidgetChanged +=
                new EventHandler<MainSelectedWidgetChangedEventArgs>(pageEditor_MainSelectedWidgetChanged);
        }

        /// <summary>
        /// 直接调用Redo(e)，来实现重做。
        /// </summary>
        void modifingItemsList_RedoExecuted(object sender, ModifingEventArgs<Action, ModifingInfo> e)
        {
            Redo(e);
        }

        /// <summary>
        /// 直接调用Uedo(e)，来实现撤销。
        /// </summary>
        void modifingItemsList_UndoExecuted(object sender, ModifingEventArgs<Action, ModifingInfo> e)
        {
            Undo(e);
        }

        /// <summary>
        /// 将pageEditor移动到所有pageEditor的尾部。
        /// </summary>
        /// <param name="pageEditor">要移动的pageEditor。</param>
        public void MoveToEnd(PageEditor pageEditor)
        {
            if (pageEditor == null) return;
            if (this.mainStackPanel.Children.Contains(pageEditor) == false) return;

            int curIndex = this.mainStackPanel.Children.IndexOf(pageEditor);

            if (curIndex == (this.mainStackPanel.Children.Count - 1)) return;//已在最后一位。

            int newIndex = this.mainStackPanel.Children.Count - 1;

            this.mainStackPanel.Children.Remove(pageEditor);
            this.mainStackPanel.Children.Add(pageEditor);
        }

        /// <summary>
        /// 将pageEditor与它前面一个pageEditor交换位置。
        /// </summary>
        /// <param name="pageEditor">要前移的pageEditor。</param>
        public void MoveToPreview(PageEditor pageEditor)
        {
            if (pageEditor == null) return;
            if (this.mainStackPanel.Children.Contains(pageEditor) == false) return;

            int curIndex = this.mainStackPanel.Children.IndexOf(pageEditor);

            if (curIndex <= 0) return;//已在第一位。

            int newIndex = curIndex - 1;

            this.mainStackPanel.Children.Remove(pageEditor);
            this.mainStackPanel.Children.Insert(newIndex, pageEditor);
        }

        /// <summary>
        /// 将pageEditor与它后面一个pageEditor交换位置。
        /// </summary>
        /// <param name="pageEditor">要后移的pageEditor。</param>
        public void MoveToNext(PageEditor pageEditor)
        {
            if (pageEditor == null) return;
            if (this.mainStackPanel.Children.Contains(pageEditor) == false) return;

            int curIndex = this.mainStackPanel.Children.IndexOf(pageEditor);

            if (curIndex >= (this.mainStackPanel.Children.Count - 1)) return;//已经在最后一位。

            int newIndex = curIndex + 1;

            this.mainStackPanel.Children.Remove(pageEditor);
            this.mainStackPanel.Children.Insert(newIndex, pageEditor);
        }

        /// <summary>
        /// 将pageEditor移动到所有pageEditor的第一位。
        /// </summary>
        /// <param name="pageEditor">要移动的pageEditor。</param>
        public void MoveToStart(PageEditor pageEditor)
        {
            if (pageEditor == null) return;
            if (this.mainStackPanel.Children.Contains(pageEditor) == false) return;

            int curIndex = this.mainStackPanel.Children.IndexOf(pageEditor);

            if (curIndex == 0) return;//已在第一位。

            int newIndex = 0;

            this.mainStackPanel.Children.Remove(pageEditor);
            this.mainStackPanel.Children.Insert(newIndex, pageEditor);
        }

        /// <summary>
        /// 活动部件被改变。
        /// </summary>
        void pageEditor_MainSelectedWidgetChanged(object sender, MainSelectedWidgetChangedEventArgs e)
        {
            if (e != null && e.NewMainSelectedWidget != null)
            {
                this.previewMainSelectedWidgetIDs.Add(e.NewMainSelectedWidget.Id);
            }

            OnMainSelectedWidgetChanged(this, e);
        }

        /// <summary>
        /// 触发事件。
        /// </summary>
        void pageEditor_MouseLeftButtonDroped(object sender, MouseLeftButtonDraggingEventArgs e)
        {
            OnMouseLeftButtonDropped(this, e);
        }

        /// <summary>
        /// 真正执行“重做”操作。此处【不必逆序处理】“Action”。
        /// </summary>
        /// <param name="e"></param>
        private void Redo(ModifingEventArgs<Action, ModifingInfo> e)
        {
            ModifingItem<Action, ModifingInfo> mi = e.ModifingItem;

            for (int i = 0; i < e.ModifingItem.ActionCount; i++)//重做，正序
            {
                Action action = e.ModifingItem[i];
                switch (action.ActionType)
                {
                    case ActionType.PropertyChanged:
                        {
                            PageEditor pe = this.GetPageEditor(action.PageEditorID);
                            if (pe != null)
                            {
                                Widgets.Widget w = pe.GetWidget(action.WidgetID);
                                if (w != null)
                                {
                                    w.SetProperty(action.PropertyName, action.NewDataText);
                                }
                            }

                            break;
                        }
                    case ActionType.WidgetAdded:
                        {
                            PageEditor pe = this.GetPageEditor(action.PageEditorID);
                            if (pe != null)
                            {
                                XmlNode peWidgetSetNode = pe.WidgetSetNode;
                                if (peWidgetSetNode != null)
                                {
                                    XmlNode newXmlNode = peWidgetSetNode.AppendXmlAsChild(action.NewDataText);
                                    if (newXmlNode != null)
                                    {

                                        Widgets.Widget w = Widgets.Widget.BuildWidget(pe, newXmlNode);
                                        if (w != null)
                                        {
                                            w.XmlData = newXmlNode;

                                            pe.AddWidget(w);

                                            //有必要，不然“组”部件的尺寸会出问题。
                                            Widgets.ContentWidget cw = w as Widgets.ContentWidget;
                                            if (cw != null) cw.RefreshLocation();
                                        }
                                    }
                                }
                            }

                            break;
                        }
                    case ActionType.WidgetDeleted:
                        {
                            PageEditor pe = this.GetPageEditor(action.PageEditorID);
                            if (pe != null)
                            {
                                Widgets.Widget w = pe.GetWidget(action.WidgetID);
                                if (w != null)
                                {
                                    if (pe.XmlData != null && pe.WidgetSetNode != null)
                                    {
                                        XmlNode peWidgetSetNode = pe.WidgetSetNode;

                                        if (w.XmlData != null && w.XmlData.ParentNode == peWidgetSetNode)
                                        {
                                            peWidgetSetNode.RemoveChild(w.XmlData);
                                        }
                                    }

                                    pe.RemoveWidget(w);
                                }
                            }

                            break;
                        }
                    case ActionType.PageHeaderChanged:
                        {
                            if (action.NewDataText != null)
                            {
                                this.PageHeader = action.NewDataText;
                            }

                            break;
                        }
                    case ActionType.PageFooterChanged:
                        {
                            if (action.NewDataText != null)
                            {
                                this.PageFooter = action.NewDataText;
                            }

                            break;
                        }
                    case ActionType.PageRightSideColorChanged:
                        {
                            PageEditor pe = this.GetPageEditor(action.PageEditorID);
                            if (pe != null)
                            {
                                pe.PageRightSideBackColor = Tools.BrushManager.GetBrush(action.NewDataText);
                                if (this.masterWindow != null)
                                {
                                    this.masterWindow.RefreshPageView();
                                }
                            }

                            break;
                        }
                    case ActionType.PageTitleChanged:
                        {
                            PageEditor pe = this.GetPageEditor(action.PageEditorID);
                            if (pe != null)
                            {
                                pe.PageTitle = action.NewDataText;
                            }

                            break;
                        }
                    case ActionType.SetPageCommentText:
                        {
                            PageEditor pe = this.GetPageEditor(action.PageEditorID);
                            if (pe != null)
                            {
                                pe.CommentText = action.NewDataText;
                            }

                            break;
                        }
                    case ActionType.ShowPageNumber:
                        {
                            if(action.NewDataText != null)
                            {
                                if (bool.TryParse(action.NewDataText, out bool isShowPageNumber))
                                {
                                    this.IsShowPageNumber = isShowPageNumber;
                                }
                            }
                            break;
                        }
                    case ActionType.PageLeftSideColorChanged:
                        {
                            PageEditor pe = this.GetPageEditor(action.PageEditorID);
                            if (pe != null)
                            {
                                pe.PageLeftSideBackColor = Tools.BrushManager.GetBrush(action.NewDataText);
                                if (this.masterWindow != null)
                                {
                                    this.masterWindow.RefreshPageView();
                                }
                            }

                            break;
                        }
                    case ActionType.TileMode:
                        {
                            if (action.NewDataText != null && action.NewDataText.Length > 0)
                            {
                                this.DefaultBackTileMode = (TileMode)Enum.Parse(typeof(TileMode), action.NewDataText);
                            }

                            break;
                        }
                    case ActionType.DefaultBackgroundChanged:
                        {
                            if (action.NewDataText != null && action.NewDataText.Length > 0)
                            {
                                this.DocumentBackgroundText = action.NewDataText;
                            }

                            break;
                        }
                    case ActionType.DefaultFontSizeChanged:
                        {
                            if (action.NewDataText != null && action.NewDataText.Length > 0)
                            {
                                this.DefaultFontSize = double.Parse(action.NewDataText);
                            }

                            break;
                        }
                    //2012年6月14日。已废弃。与部件本身相关的，改由“部件样式”决定。
                    //case ActionType.DefaultForegroundChanged:
                    //    {
                    //        if (action.NewDataText != null && action.NewDataText.Length > 0)
                    //        {
                    //            this.DefaultForeground = BrushManager.GetBrushByEnglishName(action.NewDataText);
                    //        }

                    //        break;
                    //    }
                    case ActionType.SetWidgetStyle:
                        {
                            if (action.NewDataText != null && action.NewDataText.Length > 0)
                            {
                                WidgetStyle newStyle = WidgetStyle.FromString(action.NewDataText);
                                if (newStyle != null)
                                {
                                    this.SetWidgetStyle(newStyle);
                                }
                            }

                            break;
                        }
                    case ActionType.WidgetStartCtrlBrushChanged:
                        {
                            if (action.NewDataText != null && action.NewDataText.Length > 0)
                            {
                                this.WidgetStartControlerBrush = BrushManager.GetBrushByEnglishName(action.NewDataText);
                            }

                            break;
                        }
                    case ActionType.WidgetCenterCtrlBrushChanged:
                        {
                            if (action.NewDataText != null && action.NewDataText.Length > 0)
                            {
                                this.WidgetCenterControlerBrush = BrushManager.GetBrushByEnglishName(action.NewDataText);
                            }

                            break;
                        }
                    case ActionType.WidgetEndCtrlBrushChanged:
                        {
                            if (action.NewDataText != null && action.NewDataText.Length > 0)
                            {
                                this.WidgetEndControlerBrush = BrushManager.GetBrushByEnglishName(action.NewDataText);
                            }

                            break;
                        }
                    case ActionType.WidgetSelectionAdornerBrushChanged:
                        {
                            if (action.NewDataText != null && action.NewDataText.Length > 0)
                            {
                                this.WidgetSelectionAdornerBrush = BrushManager.GetBrushByEnglishName(action.NewDataText);
                            }

                            break;
                        }
                    case ActionType.MovePageEditor:
                        {
                            int oldIndex = int.Parse(action.OldDataText);
                            int newIndex = int.Parse(action.NewDataText);

                            PageEditor pe = this.GetPageEditor(action.PageEditorID);
                            XmlNode pageSetNode = this.PageSetNode;
                            if (pageSetNode != null && pe.XmlData.ParentNode == pageSetNode)
                            {
                                pageSetNode.RemoveChild(pe.XmlData);
                                pageSetNode.InsertChildNodeAt(newIndex, pe.XmlData);

                                if (this.mainStackPanel.Children.Contains(pe))
                                {
                                    this.mainStackPanel.Children.Remove(pe);
                                    this.mainStackPanel.Children.Insert(newIndex, pe);
                                }
                            }

                            this.RefreshPaginations();
                            break;
                        }
                    case ActionType.PageEditorAdded:
                        {
                            PageEditor addedPageEditor = new PageEditor(this);
                            XmlNode pageSetNode = this.PageSetNode;

                            if (pageSetNode != null)
                            {
                                XmlNode newNode = pageSetNode.InsertXmlAt(action.NewDataText, action.PageEditorIndex);
                                if (newNode != null)
                                {
                                    addedPageEditor.XmlData = newNode;
                                    this.mainStackPanel.Children.Insert(action.PageEditorIndex, addedPageEditor);
                                }
                            }

                            this.RefreshPaginations();
                            break;
                        }
                    case ActionType.PageEditorDeleted:
                        {
                            PageEditor addedPageEditor = this.GetPageEditor(action.PageEditorID);
                            if (addedPageEditor != null)
                            {
                                XmlNode pageSetNode = this.PageSetNode;
                                if (pageSetNode != null && addedPageEditor.XmlData != null &&
                                    addedPageEditor.XmlData.ParentNode == pageSetNode)
                                {
                                    pageSetNode.RemoveChild(addedPageEditor.XmlData);
                                }

                                if (this.mainStackPanel.Children.Contains(addedPageEditor))
                                {
                                    this.mainStackPanel.Children.Remove(addedPageEditor);
                                }
                            }

                            this.RefreshPaginations();
                            break;
                        }
                    case ActionType.PaperDirectionSetting:
                        {
                            PageEditor pe = this.GetPageEditor(action.PageEditorID);
                            if (pe != null)
                            {
                                pe.PaperDirection = (Orientation)Enum.Parse(typeof(Orientation), action.NewDataText);
                            }

                            this.RefreshPaginations();
                            break;
                        }
                    case ActionType.PaperSizeSetting:
                        {
                            PageEditor pe = this.GetPageEditor(action.PageEditorID);
                            if (pe != null)
                            {
                                pe.PaperSizeText = action.NewDataText;
                            }

                            this.RefreshPaginations();
                            break;
                        }
                    case ActionType.PageLongSideMultipleChanged:
                        {
                            PageEditor pe = this.GetPageEditor(action.PageEditorID);
                            if (pe != null)
                            {
                                pe.PageLongSideMultiple = int.Parse(action.NewDataText);
                            }
                            break;
                        }
                    case ActionType.PageShortSideMultipleChanged:
                        {
                            PageEditor pe = this.GetPageEditor(action.PageEditorID);
                            if (pe != null)
                            {
                                pe.PageShortSideMultiple = int.Parse(action.NewDataText);
                            }
                            break;
                        }
                    case ActionType.SetAssistGridForm:
                        {
                            //this.assistGridForm = (AssistGridForm)Enum.Parse(typeof(AssistGridForm), action.NewDataText);
                            //this.RefreshAssistGridForm();

                            PageEditor pe = this.GetPageEditor(action.PageEditorID);
                            pe.AssistGridForm = (AssistGridForm)Enum.Parse(typeof(AssistGridForm), action.NewDataText);

                            break;
                        }
                }
            }

            //重做后，恢复此操作执行后的选定状态。
            foreach (UIElement ue in this.mainStackPanel.Children)
            {
                PageEditor pe = ue as PageEditor;
                if (pe == null) continue;

                if (mi.ModifingInfo.NewMainSelectedPageEditorID == pe.Id)
                {
                    pe.IsMainSelected = true;
                }
                else
                {
                    if (mi.ModifingInfo.NewSelectedPageEditorIDList != null &&
                        mi.ModifingInfo.NewSelectedPageEditorIDList.Contains(pe.Id))
                    {
                        pe.IsSelected = true;
                    }
                    else
                    {
                        pe.IsSelected = false;
                    }
                }
            }

            List<Widgets.Widget> allWidgetList = this.GetListOfAllWidgets();

            if (mi.ModifingInfo.NewSelectedWidgetIDList != null &&
                mi.ModifingInfo.NewSelectedWidgetIDList.Count > 0)
            {
                foreach (Widgets.Widget w in allWidgetList)
                {
                    if (mi.ModifingInfo.NewSelectedWidgetIDList.Contains(w.Id))
                    {
                        w.IsSelected = true;
                    }
                    else
                    {
                        w.IsSelected = false;
                    }

                    if (mi.ModifingInfo.NewMainSelectedWidgetID == w.Id)
                    {
                        w.IsMainSelected = true;
                    }

                    ILinkableLine linkedLine = w as ILinkableLine;
                    if (linkedLine != null && linkedLine.IsLinked)
                    {
                        linkedLine.RefreshLocation();
                    }
                }
            }

            this.RefreshModifingDescription();

            if (mi.NeedRefreshAutoNumberStrings)
            {
                this.RefreshAutoNumberStrings();//刷新自动编号。
            }
        }

        ///// <summary>
        ///// 2014年2月5日，此方法被废弃。由于辅助线具备特定功能，因此，不再由EdotorManager统一管理，而是由各页面自行负责。
        ///// </summary>
        //[Obsolete("此方法已于2014年2月5日弃用")]
        //private void RefreshAssistGridForm()
        //{
        //    foreach (UIElement ue in this.mainStackPanel.Children)
        //    {
        //        PageEditor pe = ue as PageEditor;
        //        if (pe == null) continue;

        //        pe.AssistGridForm = this.assistGridForm;
        //    }

        //    if (this.masterWindow != null)
        //    {
        //        this.masterWindow.RefreshAssistGridFormButtons(this.assistGridForm);
        //    }
        //}

        /// <summary>
        /// 刷新所有文本块标题的自动编号。ArrowsLineWidget不支持。
        /// 其它部件即使被设置为标题，也只是字形、字号的变化，而不包括自动编号。
        /// </summary>
        public void RefreshAutoNumberStrings(ModifingItem<Action, ModifingInfo> mi = null, ModifingInfo info = null)
        {
            List<PageEditor> allPages = this.GetAllPageEditors();
            if (allPages.Count <= 0) return;

            int n1Level = 1; int n2Level = 1; int n3Level = 1; int n4Level = 1; int n5Level = 1;
            //只有T1-T4才支持自动编号。T5暂时只是“◆ ”开头，做成项目列表的样子。

            List<Widget> allWidgets = new List<Widget>();

            AutoNumberRefreshedEventArgs eventArgs = new AutoNumberRefreshedEventArgs();

            foreach (PageEditor pe in allPages)
            {
                List<TextArea> widgetsInPage = pe.GetAllTextAreaWidgets();//2012年6月25日晚，改为只允许文本块支持自动编号。
                if (widgetsInPage.Count <= 0) continue;

                widgetsInPage.Sort(new Tools.WidgetCenterYCompareClass());//按纵坐标排序。
                allWidgets.AddRange(widgetsInPage);

                eventArgs.pageItems.Add(widgetsInPage);
            }

            #region 刷新自动编号

            foreach (Widgets.Widget w in allWidgets)
            {
                switch (w.TitleLevel)
                {
                    case Enums.TitleStyle.MainTitle:
                        {
                            if (w.AutoNumberString != string.Empty)//主标题负责“切断自动编号”但本身不显示编号。
                                w.AutoNumberString = string.Empty;

                            n1Level = 1; n2Level = 1; n3Level = 1; n4Level = 1; n5Level = 1;//“切断”自动编号。
                            break;
                        }
                    case Enums.TitleStyle.T1:
                        {
                            string newAutoNumberString = TitleManager.BuildAutoNumberString(Enums.TitleStyle.T1, n1Level);
                            if (w.AutoNumberString != newAutoNumberString)
                            {
                                w.AutoNumberString = newAutoNumberString;
                            }

                            n1Level++;

                            n2Level = 1; n3Level = 1; n4Level = 1; n5Level = 1;//“切断”自动编号。
                            break;
                        }
                    case Enums.TitleStyle.T2:
                        {
                            string newAutoNumberString = TitleManager.BuildAutoNumberString(Enums.TitleStyle.T2, n2Level);
                            if (w.AutoNumberString != newAutoNumberString)
                            {
                                w.AutoNumberString = newAutoNumberString;
                            }

                            n2Level++;

                            n3Level = 1; n4Level = 1; n5Level = 1;//“切断”自动编号。
                            break;
                        }
                    case Enums.TitleStyle.T3:
                        {
                            string newAutoNumberString = TitleManager.BuildAutoNumberString(Enums.TitleStyle.T3, n3Level);
                            if (w.AutoNumberString != newAutoNumberString)
                            {
                                w.AutoNumberString = newAutoNumberString;
                            }

                            n3Level++;

                            n4Level = 1; n5Level = 1;//“切断”自动编号。
                            break;
                        }
                    case Enums.TitleStyle.T4:
                        {
                            string newAutoNumberString = TitleManager.BuildAutoNumberString(Enums.TitleStyle.T4, n4Level);
                            if (w.AutoNumberString != newAutoNumberString)
                            {
                                w.AutoNumberString = newAutoNumberString;
                            }

                            n4Level++;

                            n5Level = 1;//“切断”自动编号。
                            break;
                        }
                    case Enums.TitleStyle.T5:
                        {
                            string newAutoNumberString = TitleManager.BuildAutoNumberString(Enums.TitleStyle.T5, n5Level);
                            if (w.AutoNumberString != newAutoNumberString)
                            {
                                w.AutoNumberString = newAutoNumberString;
                            }

                            n5Level++;

                            break;
                        }
                    default:
                        {
                            if (w.AutoNumberString != string.Empty)
                            {
                                w.AutoNumberString = string.Empty;
                            }

                            break;
                        }
                }
            }

            #endregion

            #region 为主窗口刷新大纲视图而准备。

            OnAutoNumberRefreshed(this, eventArgs);//主窗口应处理此事件。

            #endregion

            //自动编号可能造成连接线位移
            bool needRegisterModifingItem = false;//诸多方法会调用此方法，很可能已经注册过“修改项目”。

            if (info == null)
                info = new ModifingInfo() { ModifingDescription = "刷新连接线位置" };

            if (mi == null)
            {
                needRegisterModifingItem = true;
                mi = new ModifingItem<Action, ModifingInfo>(info);
            }

            this.GetSelectedPageEditorStatus(info);
            this.GetSelectedWidgetStatus_Old(info);

            foreach (PageEditor pe in allPages)
            {
                List<Widget> list = new List<Widget>();
                var textAreasList = pe.GetAllTextAreaWidgets();
                foreach (var ta in textAreasList)
                {
                    ta.InvalidateArrange(); ta.UpdateLayout();

                    list.Add(ta);
                }
                pe.RefreshLinkedLines(mi, pe.GetLinkedLines(list));
            }

            if (needRegisterModifingItem == true)
            {
                this.RegisterModifingItem(mi);
            }
        }

        public void RefreshContentWidgetsLinkToolTip()
        {
            List<PageEditor> allPages = this.GetAllPageEditors();
            if (allPages.Count <= 0) return;

            foreach (PageEditor pe in allPages)
            {
                foreach (UIElement ue in pe.Children)
                {
                    Widgets.ContentWidget cw = ue as Widgets.ContentWidget;
                    if (cw == null) continue;

                    cw.RefreshLinkedPageEditorId();
                }
            }
        }

        /// <summary>
        /// 刷新默认背景色。
        /// </summary>
        private void RefreshDocumentBackground()
        {
            this.OnPropertyChanged(this, new PropertyChangedEventArgs(XmlTags.DocumentBackgroundTag));

            OnDocumentBackgroundChanged(this, new DocumentBackgroundChangedEventArgs()
            {
                NewDocumentBackground = documentBackground,
            });
        }

        private void RefreshDefaultFontSize()
        {
            this.OnPropertyChanged(this, new PropertyChangedEventArgs(XmlTags.DefaultFontSizeTag));

            //if (masterWindow != null && masterWindow.MainScrollViewer != null)
            //{
            //    masterWindow.MainScrollViewer.FontSize = defaultFontSize;
            //}
            //这会导致一些意外问题：当部件内部文本字号较小时，会在顶端显示一些不需要的空白。

            //默认字号变化会引起标题等文本字号的变化。
            List<PageEditor> allpages = this.GetAllPageEditors();
            if (allpages != null && allpages.Count > 0)
            {
                foreach (PageEditor pe in allpages)
                {
                    List<Widget> allWidgets = pe.GetAllWidgets();
                    if (allWidgets != null && allWidgets.Count > 0)
                    {
                        foreach (Widget w in allWidgets)
                        {
                            //w.RefreshText();//下一行包括了这个调用。
                            w.RefreshDefaultFontSize();
                        }
                    }
                }
            }
        }

        ///// <summary>
        ///// 刷新默认前景色。
        ///// </summary>
        //public void RefreshDefaultForeground()
        //{
        //    this.OnPropertyChanged(this, new PropertyChangedEventArgs(XmlTags.DefaultForegroundTag));

        //还需要重设默认属性，以使新添加的部件前景色不受影响。
        //WidgetDefaultProperties.ResetAll();
        //2012年6月14日，废弃“配色方案”对部件前景的控制。部件前景色完全改由“部件样式”控制。
        //并将“文档配色”与重做的“部件样式”合并到“选项”对话框（由“配色”对话框改造而来）中来完成。

        //RefreshAllWidgetsForeColor();
        //2012年2月17日改为在配色后，检查是否有部件前景色与新背景色相同，如果相同，强行更改之。
        //}

        //public void RefreshAllWidgetsForeColor()
        //{
        //这个方法不能使用，否则会造成“看似已经更新了前景色，其实却没改”这个问题。
        //foreach (UIElement uePageEditor in this.mainStackPanel.Children)
        //{
        //    PageEditor mainPageEditor = uePageEditor as PageEditor;
        //    if (mainPageEditor == null) continue;

        //    foreach (UIElement ueWidget in mainPageEditor.Children)
        //    {
        //        Widget w = ueWidget as Widget;
        //        if (w != null)
        //        {
        //            w.RefreshWidgetForeColor(this.defaultForeground);
        //        }
        //    }
        //}            
        //}

        /// <summary>
        /// 修改页脚后刷新。
        /// </summary>
        private void RefreshPageFooter()
        {
            this.OnPropertyChanged(this, new PropertyChangedEventArgs(XmlTags.PageFooterTag));
        }

        /// <summary>
        /// 通知各页面刷新页脚位置。
        /// </summary>
        public void RefreshPageFooterLocation()
        {
            foreach (UIElement ue in this.mainStackPanel.Children)
            {
                PageEditor pe = ue as PageEditor;

                if (pe != null) pe.RefreshPageFooterLocation();
            }
        }

        /// <summary>
        /// 修改页眉后刷新。
        /// </summary>
        private void RefreshPageHeader()
        {
            this.OnPropertyChanged(this, new PropertyChangedEventArgs(XmlTags.PageHeaderTag));
        }

        /// <summary>
        /// 刷新所有页面的页号。
        /// </summary>
        public void RefreshPaginations()
        {
            int index = 1;
            int count = this.mainStackPanel.Children.Count;

            if (count == 1)
            {
                PageEditor pe = this.mainStackPanel.Children[0] as PageEditor;
                if (pe == null) return;

                pe.RefreshPagination(string.Empty);
                return;
            }

            for (int i = 0; i < count; i++)
            {
                PageEditor pe = this.mainStackPanel.Children[i] as PageEditor;
                if (pe == null) continue;

                if (this.IsShowPageNumber)
                {
                    pe.RefreshPagination(string.Format("第 {0} 页，共 {1} 页", index, count));
                }
                else
                {
                    pe.RefreshPagination("");
                }

                index++;
            }
        }

        /// <summary>
        /// 在Undo和Redo后，刷新“撤销”和“重做”按钮的ToolTip。
        /// </summary>
        private void RefreshModifingDescription()
        {
            if (Globals.MainWindow == null) return;

            if (modifingItemsList.Point < modifingItemsList.Count - 1)
            {
                Globals.MainWindow.RQBtnRedo.ToolTip = Globals.MainWindow.RBtnRedo.ToolTip =
                    "Ctrl + Y,重做：" + modifingItemsList[modifingItemsList.Point + 1].ModifingInfo.ModifingDescription;
            }
            else
            {
                Globals.MainWindow.RQBtnRedo.ToolTip = Globals.MainWindow.RBtnRedo.ToolTip =
                    "Ctrl + Y";
            }

            if (modifingItemsList.Point > -1)
            {
                Globals.MainWindow.RQBtnUndo.ToolTip = Globals.MainWindow.RBtnUndo.ToolTip =
                    "Ctrl + Z,撤销：" + modifingItemsList[modifingItemsList.Point].ModifingInfo.ModifingDescription;
            }
            else
            {
                Globals.MainWindow.RQBtnUndo.ToolTip = Globals.MainWindow.RBtnUndo.ToolTip =
                    "Ctrl + Z";
            }
        }

        /// <summary>
        /// 刷新部件选定框或控制点色彩。
        /// </summary>
        private void RefreshWidgetSelectionAdornerBrush()
        {
            this.OnPropertyChanged(this, new PropertyChangedEventArgs(XmlTags.WidgetSelectionAdornerBrush));

            foreach (UIElement pageUe in this.Children)
            {
                PageEditor pe = pageUe as PageEditor;
                if (pe == null) continue;

                foreach (UIElement widgetUe in pe.Children)
                {
                    Widgets.Widget w = widgetUe as Widgets.Widget;
                    if (w == null || w.IsSelected == false) continue;

                    w.RefreshIsSelected();
                }
            }

            this.BuildAssistLineBrushes();
            //this.RefreshAssistGridForm();
            foreach (UIElement ue in this.mainStackPanel.Children)
            {
                var pe = ue as PageEditor;
                if (pe == null) continue;

                pe.RefreshAssistGridForm();
            }

            //放大镜边框色与部件选取色相同。
            this.magnifier.BorderBrush = this.widgetSelectionAdornerBrush;
        }

        /// <summary>
        /// 根据指定的WidgetStyle通知文档中所有部件刷新相关属性。
        /// ——除非部件自身的Xml后台数据中定义了这些属性的值，否则，部件应按这里指定的Style来呈现。
        /// 
        /// ★此方法用于某种部件的默认样式改变后刷新相关部件的状态。
        /// </summary>
        /// <param name="newStyle"></param>
        public void RefreshWidgetStyle(WidgetStyle newStyle)
        {
            List<PageEditor> allpages = GetAllPageEditors();
            if (allpages == null || allpages.Count <= 0) return;

            foreach (PageEditor pe in allpages)
            {
                List<Widgets.Widget> allWidgets = pe.GetAllWidgets(false);

                foreach (Widgets.Widget w in allWidgets)
                {
                    w.BuildWidgetStylePropertiesAndRefresh();
                }
            }
        }

        /// <summary>
        /// 移除指定的pageEditor。如果pageEditor已经不在mainStackPanel中，不会抛出异常，而是直接返回。
        /// </summary>
        /// <param name="pageEditor"></param>
        public void RemoveEditor(PageEditor pageEditor)
        {
            if (this.mainStackPanel.Children.Contains(pageEditor) == false)
                return;

            this.mainStackPanel.Children.Remove(pageEditor);
        }

        /// <summary>
        /// 如果找到的第一个处于IsMainSelected状态的PageEditor，
        /// 则尝试滚动ScrollViewer来显示之。
        /// 
        /// 2012年2月16日，终于解决了居中对齐这个问题。
        /// </summary>
        /// <param name="baseCenterAlignment">默认按中心显示。</param>
        public void TryToDisplayPageEditor(PageEditor pe, bool baseCenterAlignment = true)
        {
            if (masterWindow == null || pe == null ||
                this.mainStackPanel.Children.Contains(pe) == false)
                return;

            Point basePoint = new Point(0, 0);

            pe.InvalidateArrange(); pe.UpdateLayout();

            Point peLocation = pe.TranslatePoint(basePoint, this.mainStackPanel);

            if (baseCenterAlignment)
            {
                //居中对齐
                double x = this.scaleTransform.ScaleX;
                double y = this.scaleTransform.ScaleY;
                masterWindow.MainScrollViewer.ScrollToHorizontalOffset(peLocation.X * x -
                    (masterWindow.MainScrollViewer.ViewportWidth - pe.ActualWidth * x) / 2 + this.Margin.Left);
                masterWindow.MainScrollViewer.ScrollToVerticalOffset(peLocation.Y * y -
                    (masterWindow.MainScrollViewer.ViewportHeight - pe.ActualHeight * y) / 2 + this.Margin.Top);
            }
            else
            {
                masterWindow.MainScrollViewer.ScrollToHorizontalOffset(peLocation.X - this.Margin.Left);
                masterWindow.MainScrollViewer.ScrollToVerticalOffset(peLocation.Y - this.Margin.Top);
            }

            this.ClearWidgetsSelection();//避免误选定。
        }

        /// <summary>
        /// 真正执行“撤销”操作。要注意【逆序处理】“Action”。
        /// </summary>
        /// <param name="e"></param>
        private void Undo(ModifingEventArgs<Action, ModifingInfo> e)
        {
            ModifingItem<Action, ModifingInfo> mi = e.ModifingItem;

            for (int i = e.ModifingItem.ActionCount - 1; i >= 0; i--)//撤销，倒序
            {
                Action action = e.ModifingItem[i];
                switch (action.ActionType)
                {
                    case ActionType.PropertyChanged:
                        {
                            PageEditor pe = this.GetPageEditor(action.PageEditorID);
                            if (pe != null)
                            {
                                Widgets.Widget w = pe.GetWidget(action.WidgetID);
                                if (w != null)
                                {
                                    w.SetProperty(action.PropertyName, action.OldDataText);
                                }
                            }

                            break;
                        }
                    case ActionType.WidgetAdded:
                        {
                            PageEditor pe = this.GetPageEditor(action.PageEditorID);
                            if (pe != null)
                            {
                                Widgets.Widget w = pe.GetWidget(action.WidgetID);
                                if (w != null)
                                {
                                    if (pe.XmlData != null && pe.WidgetSetNode != null)
                                    {
                                        XmlNode peWidgetSetNode = pe.WidgetSetNode;

                                        if (w.XmlData != null && w.XmlData.ParentNode == peWidgetSetNode)
                                        {
                                            peWidgetSetNode.RemoveChild(w.XmlData);
                                        }
                                    }

                                    pe.RemoveWidget(w);
                                }
                            }

                            break;
                        }
                    case ActionType.WidgetDeleted:
                        {
                            PageEditor pe = this.GetPageEditor(action.PageEditorID);
                            if (pe != null)
                            {
                                XmlNode peWidgetSetNode = pe.WidgetSetNode;
                                if (peWidgetSetNode != null)
                                {
                                    XmlNode oldXmlNode = peWidgetSetNode.AppendXmlAsChild(action.OldDataText);
                                    if (oldXmlNode != null)
                                    {

                                        Widgets.Widget w = Widgets.Widget.BuildWidget(pe, oldXmlNode);
                                        if (w != null)
                                        {
                                            w.XmlData = oldXmlNode;

                                            pe.AddWidget(w);

                                            //有必要，不然“组”部件的尺寸会出问题。
                                            ContentWidget cw = w as ContentWidget;
                                            if (cw != null) cw.RefreshLocation();
                                        }
                                    }
                                }
                            }

                            break;
                        }
                    case ActionType.PageHeaderChanged:
                        {
                            if (action.OldDataText != null)
                            {
                                this.PageHeader = action.OldDataText;
                            }

                            break;
                        }
                    case ActionType.PageLeftSideColorChanged:
                        {
                            PageEditor pe = this.GetPageEditor(action.PageEditorID);
                            if (pe != null)
                            {
                                pe.PageLeftSideBackColor = Tools.BrushManager.GetBrush(action.OldDataText);
                                if (this.masterWindow != null)
                                {
                                    this.masterWindow.RefreshPageView();
                                }
                            }

                            break;
                        }
                    case ActionType.PageFooterChanged:
                        {
                            if (action.OldDataText != null)
                            {
                                Globals.MainWindow.EditorManager.PageFooter = action.OldDataText;
                            }

                            break;
                        }
                    case ActionType.PageRightSideColorChanged:
                        {
                            PageEditor pe = this.GetPageEditor(action.PageEditorID);
                            if (pe != null)
                            {
                                pe.PageRightSideBackColor = Tools.BrushManager.GetBrush(action.OldDataText);
                                if (this.masterWindow != null)
                                {
                                    this.masterWindow.RefreshPageView();
                                }
                            }

                            break;
                        }
                    case ActionType.PageTitleChanged:
                        {
                            PageEditor pe = this.GetPageEditor(action.PageEditorID);
                            if (pe != null)
                            {
                                pe.PageTitle = action.OldDataText;
                            }

                            break;
                        }
                    case ActionType.SetPageCommentText:
                        {
                            PageEditor pe = this.GetPageEditor(action.PageEditorID);
                            if (pe != null)
                            {
                                pe.CommentText = action.OldDataText;
                            }

                            break;
                        }
                    case ActionType.ShowPageNumber:
                        {
                            if (action.OldDataText != null)
                            {
                                if (bool.TryParse(action.OldDataText, out bool isShowPageNumber))
                                {
                                    this.IsShowPageNumber = isShowPageNumber;
                                }
                            }
                            break;
                        }
                    case ActionType.TileMode:
                        {
                            if (action.OldDataText != null && action.OldDataText.Length > 0)
                            {
                                this.DefaultBackTileMode = (TileMode)Enum.Parse(typeof(TileMode), action.OldDataText);
                            }

                            break;
                        }
                    case ActionType.DefaultBackgroundChanged:
                        {
                            this.DocumentBackgroundText = action.OldDataText;
                            break;
                        }
                    case ActionType.DefaultFontSizeChanged:
                        {
                            if (action.OldDataText != null && action.OldDataText.Length > 0)
                            {
                                this.DefaultFontSize = double.Parse(action.OldDataText);
                            }

                            break;
                        }
                    //2012年6月14日。已废弃。与部件本身相关的，改由“部件样式”决定。
                    //case ActionType.DefaultForegroundChanged:
                    //    {
                    //        if (action.OldDataText != null && action.OldDataText.Length > 0)
                    //        {
                    //            this.DefaultForeground = BrushManager.GetBrushByEnglishName(action.OldDataText);
                    //        }

                    //        break;
                    //    }
                    case ActionType.SetWidgetStyle:
                        {
                            if (action.OldDataText != null && action.OldDataText.Length > 0)
                            {
                                WidgetStyle oldStyle = WidgetStyle.FromString(action.OldDataText);
                                if (oldStyle != null)
                                {
                                    this.SetWidgetStyle(oldStyle);
                                }
                            }

                            break;
                        }
                    case ActionType.WidgetStartCtrlBrushChanged:
                        {
                            if (action.OldDataText != null && action.OldDataText.Length > 0)
                            {
                                this.WidgetStartControlerBrush = BrushManager.GetBrushByEnglishName(action.OldDataText);
                            }

                            break;
                        }
                    case ActionType.WidgetCenterCtrlBrushChanged:
                        {
                            if (action.OldDataText != null && action.OldDataText.Length > 0)
                            {
                                this.WidgetCenterControlerBrush = BrushManager.GetBrushByEnglishName(action.OldDataText);
                            }

                            break;
                        }
                    case ActionType.WidgetEndCtrlBrushChanged:
                        {
                            if (action.OldDataText != null && action.OldDataText.Length > 0)
                            {
                                this.WidgetEndControlerBrush = BrushManager.GetBrushByEnglishName(action.OldDataText);
                            }

                            break;
                        }
                    case ActionType.WidgetSelectionAdornerBrushChanged:
                        {
                            if (action.OldDataText != null && action.OldDataText.Length > 0)
                            {
                                this.WidgetSelectionAdornerBrush = BrushManager.GetBrushByEnglishName(action.OldDataText);
                            }

                            break;
                        }
                    case ActionType.MovePageEditor:
                        {
                            int oldIndex = int.Parse(action.OldDataText);
                            int newIndex = int.Parse(action.NewDataText);

                            PageEditor pe = this.GetPageEditor(action.PageEditorID);
                            XmlNode pageSetNode = this.PageSetNode;
                            if (pageSetNode != null && pe.XmlData.ParentNode == pageSetNode)
                            {
                                pageSetNode.RemoveChild(pe.XmlData);
                                pageSetNode.InsertChildNodeAt(oldIndex, pe.XmlData);

                                if (this.mainStackPanel.Children.Contains(pe))
                                {
                                    this.mainStackPanel.Children.Remove(pe);
                                    this.mainStackPanel.Children.Insert(oldIndex, pe);
                                }
                            }

                            this.RefreshPaginations();
                            break;
                        }
                    case ActionType.PageEditorAdded:
                        {
                            PageEditor addedPageEditor = this.GetPageEditor(action.PageEditorID);
                            if (addedPageEditor != null)
                            {
                                XmlNode pageSetNode = this.PageSetNode;
                                if (pageSetNode != null && addedPageEditor.XmlData != null &&
                                    addedPageEditor.XmlData.ParentNode == pageSetNode)
                                {
                                    pageSetNode.RemoveChild(addedPageEditor.XmlData);
                                }

                                if (this.mainStackPanel.Children.Contains(addedPageEditor))
                                {
                                    this.mainStackPanel.Children.Remove(addedPageEditor);
                                }
                            }

                            this.RefreshPaginations();
                            break;
                        }
                    case ActionType.PageEditorDeleted:
                        {
                            PageEditor addedPageEditor = new PageEditor(this);
                            XmlNode pageSetNode = this.PageSetNode;

                            if (pageSetNode != null)
                            {
                                XmlNode newNode = pageSetNode.InsertXmlAt(action.OldDataText, action.PageEditorIndex);
                                if (newNode != null)
                                {
                                    addedPageEditor.XmlData = newNode;
                                    this.mainStackPanel.Children.Insert(action.PageEditorIndex, addedPageEditor);
                                }
                            }

                            this.RefreshPaginations();
                            break;
                        }
                    case ActionType.PaperDirectionSetting:
                        {
                            PageEditor pe = this.GetPageEditor(action.PageEditorID);
                            if (pe != null)
                            {
                                pe.PaperDirection = (Orientation)Enum.Parse(typeof(Orientation), action.OldDataText);
                            }

                            this.RefreshPaginations();
                            break;
                        }
                    case ActionType.PaperSizeSetting:
                        {
                            PageEditor pe = this.GetPageEditor(action.PageEditorID);
                            if (pe != null)
                            {
                                pe.PaperSizeText = action.OldDataText;
                            }

                            this.RefreshPaginations();
                            break;
                        }
                    case ActionType.PageLongSideMultipleChanged:
                        {
                            PageEditor pe = this.GetPageEditor(action.PageEditorID);
                            if (pe != null)
                            {
                                pe.PageLongSideMultiple = int.Parse(action.OldDataText);
                            }
                            break;
                        }
                    case ActionType.PageShortSideMultipleChanged:
                        {
                            PageEditor pe = this.GetPageEditor(action.PageEditorID);
                            if (pe != null)
                            {
                                pe.PageShortSideMultiple = int.Parse(action.OldDataText);
                            }
                            break;
                        }
                    case ActionType.SetAssistGridForm:
                        {
                            //this.assistGridForm = (AssistGridForm)Enum.Parse(typeof(AssistGridForm), action.OldDataText);

                            //this.RefreshAssistGridForm();

                            PageEditor pe = this.GetPageEditor(action.PageEditorID);
                            pe.AssistGridForm = (AssistGridForm)Enum.Parse(typeof(AssistGridForm), action.OldDataText);

                            break;
                        }
                }
            }

            //撤销后，恢复此操作执行前的页面选定状态。
            foreach (UIElement ue in this.mainStackPanel.Children)
            {
                PageEditor pe = ue as PageEditor;
                if (pe == null) continue;

                if (mi.ModifingInfo.OldMainSelectedPageEditorID == pe.Id)
                {
                    pe.IsMainSelected = true;
                }
                else
                {
                    if (mi.ModifingInfo.OldSelectedPageEditorIDList != null &&
                        mi.ModifingInfo.OldSelectedPageEditorIDList.Contains(pe.Id))
                    {
                        pe.IsSelected = true;
                        continue;
                    }
                    else
                    {
                        pe.IsSelected = false;
                    }
                }
            }

            List<Widgets.Widget> allWidgetList = this.GetListOfAllWidgets();

            if (mi.ModifingInfo.OldSelectedWidgetIDList != null &&
                mi.ModifingInfo.OldSelectedWidgetIDList.Count > 0)
            {
                foreach (Widgets.Widget w in allWidgetList)
                {
                    if (mi.ModifingInfo.OldSelectedWidgetIDList.Contains(w.Id))
                    {
                        w.IsSelected = true;
                    }
                    else
                    {
                        w.IsSelected = false;
                    }

                    if (mi.ModifingInfo.OldMainSelectedWidgetID == w.Id)
                    {
                        w.IsMainSelected = true;
                    }

                    ILinkableLine linkedLine = w as ILinkableLine;
                    if (linkedLine != null && linkedLine.IsLinked)
                    {
                        linkedLine.RefreshLocation();
                    }
                }
            }

            this.RefreshModifingDescription();

            if (mi.NeedRefreshAutoNumberStrings)
            {
                this.RefreshAutoNumberStrings();//刷新自动编号。
            }
        }

        void pageEditor_WidgetControlerMoved(object sender, MouseLeftButtonDraggingEventArgs e)
        {
            OnWidgetControlerMoved(this, e);
        }

        void pageEditor_WidgetsMoved(object sender, MouseLeftButtonDraggingEventArgs e)
        {
            OnWidgetsMoved(this, e);
        }

        /// <summary>
        /// 根据部件类名取出当前文档配置中的对应当前此类部件的默认样式。（注意：不是系统默认而是文档默认）
        /// </summary>
        /// <param name="widget">部件。</param>
        public WidgetStyle GetDefaultWidgetStyle(Widget widget)
        {
            if (widget == null) return null;

            string widgetClassName = widget.GetType().Name;

            return GetDefaultWidgetStyle(widgetClassName);
        }

        /// <summary>
        /// 根据“此前活动部件ID列表”取出可能存在（有可能被删除）的部件。如果找不到，则删除条目。
        /// 此功能用于删除部件后，回到上次选定的部件。
        /// </summary>
        public Widget GetExistPreviewMainSelectedWidget()
        {
            if (this.previewMainSelectedWidgetIDs == null || this.previewMainSelectedWidgetIDs.Count <= 0) return null;

            for (int i = this.previewMainSelectedWidgetIDs.Count - 1; i >= 0; i--)
            {
                Widgets.Widget w = this.GetWidget(this.previewMainSelectedWidgetIDs[i]);
                if (w == null)
                {
                    this.previewMainSelectedWidgetIDs.RemoveAt(i);
                    continue;
                }
                else
                {
                    return w;
                }
            }

            return null;
        }

        /// <summary>
        /// 根据部件类名取出当前文档配置中的对应当前此类部件的默认样式。（注意：不是系统默认而是文档默认）
        /// </summary>
        /// <param name="widgetClassName">部件类的名称。</param>
        public WidgetStyle GetDefaultWidgetStyle(string widgetClassName)
        {
            switch (widgetClassName)
            {
                case "TextArea": return this.textAreaStyle;
                case "PictureBox": return this.pictureBoxStyle;
                case "BezierLineWidget": return this.bezierLineStyle;
                case "BracketWidget": return this.bracketStyle;
                case "EllipseWidget": return this.ellipseStyle;
                case "GroupWidget": return this.groupStyle;
                case "PolyLineWidget": return this.polyLineStyle;
                case "RectangleWidget": return this.rectangleStyle;
                case "RhombWidget": return this.rhombStyle;
                case "StraitLineWidget": return this.straitLineStyle;
                case "TriangleWidget": return this.triangleStyle;
                default: return null;
            }
        }

        /// <summary>
        /// 返回此文档中所有部件的初始默认样式组成的列表。
        /// </summary>
        public List<WidgetStyle> GetAllInitilizedWidgetStylesList()
        {
            List<WidgetStyle> resultStylesList = new List<WidgetStyle>();

            resultStylesList.Add(GetInitilizedWidgetStyle(typeof(Widgets.TextArea).Name));
            resultStylesList.Add(GetInitilizedWidgetStyle(typeof(Widgets.PictureBox).Name));
            resultStylesList.Add(GetInitilizedWidgetStyle(typeof(Widgets.BezierLineWidget).Name));

            resultStylesList.Add(GetInitilizedWidgetStyle(typeof(Widgets.BracketWidget).Name));
            resultStylesList.Add(GetInitilizedWidgetStyle(typeof(Widgets.EllipseWidget).Name));
            resultStylesList.Add(GetInitilizedWidgetStyle(typeof(Widgets.GroupWidget).Name));

            resultStylesList.Add(GetInitilizedWidgetStyle(typeof(Widgets.PolyLineWidget).Name));
            resultStylesList.Add(GetInitilizedWidgetStyle(typeof(Widgets.RectangleWidget).Name));
            resultStylesList.Add(GetInitilizedWidgetStyle(typeof(Widgets.RhombWidget).Name));

            resultStylesList.Add(GetInitilizedWidgetStyle(typeof(Widgets.StraitLineWidget).Name));
            resultStylesList.Add(GetInitilizedWidgetStyle(typeof(Widgets.TriangleWidget).Name));

            return resultStylesList;
        }
        /// <summary>
        /// 设置某一类部件的默认样式。
        /// </summary>
        /// <returns>顺利返回string.Empty。</returns>
        public string SetWidgetStyle(WidgetStyle newStyle)
        {
            if (newStyle == null) return "　　提供的部件新样式不能为null。";

            string widgetClassName = newStyle.WidgetClassName;

            switch (widgetClassName)
            {
                case "TextArea":
                    {
                        //注意要用属性而不能是字段，因为要写Xml数据。
                        this.TextAreaStyle = newStyle; break;
                    }
                case "PictureBox":
                    {
                        //注意要用属性而不能是字段，因为要写Xml数据。
                        this.PictureBoxStyle = newStyle; break;
                    }
                case "BezierLineWidget":
                    {
                        //注意要用属性而不能是字段，因为要写Xml数据。
                        this.BezierLineStyle = newStyle; break;
                    }
                case "BracketWidget":
                    {
                        //注意要用属性而不能是字段，因为要写Xml数据。
                        this.BracketStyle = newStyle; break;
                    }
                case "EllipseWidget":
                    {
                        //注意要用属性而不能是字段，因为要写Xml数据。
                        this.EllipseStyle = newStyle; break;
                    }
                case "GroupWidget":
                    {
                        //注意要用属性而不能是字段，因为要写Xml数据。
                        this.GroupStyle = newStyle; break;
                    }
                case "PolyLineWidget":
                    {
                        //注意要用属性而不能是字段，因为要写Xml数据。
                        this.PolyLineStyle = newStyle; break;
                    }
                case "RectangleWidget":
                    {
                        //注意要用属性而不能是字段，因为要写Xml数据。
                        this.RectangleStyle = newStyle; break;
                    }
                case "RhombWidget":
                    {
                        //注意要用属性而不能是字段，因为要写Xml数据。
                        this.RhombStyle = newStyle; break;
                    }
                case "StraitLineWidget":
                    {
                        //注意要用属性而不能是字段，因为要写Xml数据。
                        this.StraitLineStyle = newStyle; break;
                    }
                case "TriangleWidget":
                    {
                        //注意要用属性而不能是字段，因为要写Xml数据。
                        this.TriangleStyle = newStyle; break;
                    }
                default:
                    {
                        return "　　不能识别选定的部件的类型。";
                    }
            }

            this.RefreshWidgetStyle(newStyle);
            return string.Empty;
        }

        /// <summary>
        /// 设置某一类部件的默认样式。
        /// </summary>
        /// <param name="srcWidget">将此部件的公用属性设置为此类部件的默认属性（默认样式）。</param>
        /// <returns>顺利返回string.Empty。</returns>
        public string SetWidgetStyle(Widget srcWidget)
        {
            if (srcWidget == null) return "　　提供的部件不能为null。";

            WidgetStyle newStyle = WidgetStyle.FromWidget(srcWidget);
            if (newStyle == null) return "　　未能从指定部件取出样式。";

            string widgetClassName = srcWidget.GetType().Name;

            switch (widgetClassName)
            {
                case "TextArea":
                    {
                        this.TextAreaStyle = newStyle; break;
                    }
                case "PictureBox":
                    {
                        this.PictureBoxStyle = newStyle; break;
                    }
                case "BezierLineWidget":
                    {
                        this.BezierLineStyle = newStyle; break;
                    }
                case "BracketWidget":
                    {
                        this.BracketStyle = newStyle; break;
                    }
                case "EllipseWidget":
                    {
                        this.EllipseStyle = newStyle; break;
                    }
                case "GroupWidget":
                    {
                        this.GroupStyle = newStyle; break;
                    }
                case "PolyLineWidget":
                    {
                        this.PolyLineStyle = newStyle; break;
                    }
                case "RectangleWidget":
                    {
                        this.RectangleStyle = newStyle; break;
                    }
                case "RhombWidget":
                    {
                        this.RhombStyle = newStyle; break;
                    }
                case "StraitLineWidget":
                    {
                        this.StraitLineStyle = newStyle; break;
                    }
                case "TriangleWidget":
                    {
                        this.TriangleStyle = newStyle; break;
                    }
                default:
                    {
                        return "　　不能识别选定的部件的类型。";
                    }
            }

            this.RefreshWidgetStyle(newStyle);
            return string.Empty;
        }

        /// <summary>
        /// 返回某一类部件的初始默认样式。
        /// </summary>
        /// <param name="widgetClassName">部件类名。</param>
        public WidgetStyle GetInitilizedWidgetStyle(string widgetClassName)
        {
            WidgetStyle resultStyle = new WidgetStyle(widgetClassName);
            switch (widgetClassName)
            {
                case "TextArea":
                    {
                        resultStyle.WidgetOpacity = 1.0;
                        resultStyle.WidgetBackColor = Brushes.Transparent;
                        resultStyle.WidgetLineColor = Brushes.Black;
                        resultStyle.WidgetLineWidth = 1;
                        resultStyle.WidgetForeColor = Brushes.Black;
                        resultStyle.WidgetPadding = new Thickness(2);
                        resultStyle.IsShadowVisible = false;
                        break;
                    }
                case "PictureBox":
                    {
                        resultStyle.WidgetOpacity = 1.0;
                        resultStyle.WidgetBackColor = Brushes.Transparent;
                        resultStyle.WidgetLineColor = Brushes.Black;
                        resultStyle.WidgetLineWidth = 0;
                        resultStyle.WidgetForeColor = Brushes.Black;
                        resultStyle.WidgetPadding = new Thickness(0);
                        resultStyle.IsShadowVisible = false;
                        break;
                    }
                case "BezierLineWidget":
                    {
                        resultStyle.WidgetOpacity = 1.0;
                        resultStyle.Arrows = Enums.ArrowType.End;
                        resultStyle.WidgetBackColor = Brushes.White;
                        resultStyle.WidgetLineColor = Brushes.LimeGreen;
                        resultStyle.WidgetLineWidth = 2;
                        resultStyle.LineDash = LineDashType.DashType.Solid;
                        resultStyle.WidgetForeColor = Brushes.LimeGreen;
                        resultStyle.IsShadowVisible = false;
                        break;
                    }
                case "BracketWidget":
                    {
                        resultStyle.WidgetOpacity = 1.0;
                        resultStyle.Arrows = Enums.ArrowType.None;
                        resultStyle.WidgetBackColor = Brushes.Transparent;
                        resultStyle.WidgetLineColor = Brushes.DarkCyan;
                        resultStyle.WidgetLineWidth = 2;
                        resultStyle.LineDash = LineDashType.DashType.Solid;
                        resultStyle.WidgetForeColor = Brushes.DarkCyan;
                        resultStyle.IsShadowVisible = false;
                        break;
                    }
                case "EllipseWidget":
                    {
                        resultStyle.WidgetOpacity = 1.0;
                        resultStyle.WidgetBackColor = Brushes.MintCream;
                        resultStyle.WidgetLineWidth = 1;
                        resultStyle.WidgetLineColor = Brushes.LightSeaGreen;
                        resultStyle.LineDash = LineDashType.DashType.Solid;
                        resultStyle.WidgetForeColor = Brushes.Black;
                        resultStyle.IsShadowVisible = false;
                        break;
                    }
                case "GroupWidget":
                    {
                        resultStyle.WidgetOpacity = 1.0;
                        resultStyle.WidgetBackColor = Brushes.Transparent;
                        resultStyle.WidgetLineColor = Brushes.Black;
                        resultStyle.WidgetLineWidth = 0;
                        resultStyle.WidgetForeColor = Brushes.Black;
                        resultStyle.WidgetPadding = new Thickness(0);//这个不是10，而是0。这是为了便于计算坐标。
                        resultStyle.IsShadowVisible = false;
                        break;
                    }
                case "PolyLineWidget":
                    {
                        resultStyle.WidgetOpacity = 1.0;
                        resultStyle.Arrows = Enums.ArrowType.End;
                        resultStyle.WidgetBackColor = Brushes.White;
                        resultStyle.WidgetLineColor = Brushes.Coral;
                        resultStyle.WidgetLineWidth = 2;
                        resultStyle.LineDash = LineDashType.DashType.Solid;
                        resultStyle.WidgetForeColor = Brushes.Coral;
                        resultStyle.IsShadowVisible = false;
                        break;
                    }
                case "RectangleWidget":
                    {
                        resultStyle.WidgetOpacity = 1.0;
                        resultStyle.WidgetBackColor = Brushes.Beige;
                        resultStyle.WidgetLineWidth = 1;
                        resultStyle.WidgetLineColor = Brushes.Brown;
                        resultStyle.LineDash = LineDashType.DashType.Solid;
                        resultStyle.WidgetForeColor = Brushes.Black;
                        resultStyle.IsShadowVisible = false;
                        break;
                    }
                case "RhombWidget":
                    {
                        resultStyle.WidgetOpacity = 1.0;
                        resultStyle.WidgetBackColor = Brushes.LightGreen;
                        resultStyle.WidgetLineWidth = 1;
                        resultStyle.WidgetLineColor = Brushes.DarkGreen;
                        resultStyle.LineDash = LineDashType.DashType.Solid;
                        resultStyle.WidgetForeColor = Brushes.DarkGreen;
                        resultStyle.IsShadowVisible = false;
                        break;
                    }
                case "StraitLineWidget":
                    {
                        resultStyle.WidgetOpacity = 1.0;
                        resultStyle.Arrows = Enums.ArrowType.End;
                        resultStyle.WidgetBackColor = Brushes.White;
                        resultStyle.WidgetLineColor = Brushes.MediumVioletRed;
                        resultStyle.WidgetLineWidth = 2;
                        resultStyle.LineDash = LineDashType.DashType.Solid;
                        resultStyle.WidgetForeColor = Brushes.MediumVioletRed;
                        resultStyle.IsShadowVisible = false;
                        break;
                    }
                case "TriangleWidget":
                    {
                        resultStyle.WidgetOpacity = 1.0;
                        resultStyle.WidgetBackColor = Brushes.LightBlue;
                        resultStyle.WidgetLineWidth = 2;
                        resultStyle.WidgetLineColor = Brushes.DarkBlue;
                        resultStyle.LineDash = LineDashType.DashType.Solid;
                        resultStyle.WidgetForeColor = Brushes.DarkBlue;
                        resultStyle.IsShadowVisible = false;
                        break;
                    }
                default:
                    {
                        return null;
                    }
            }

            return resultStyle;
        }

        #endregion

        #region 事件=========================================================================================================

        public event EventHandler<AutoNumberRefreshedEventArgs> AutoNumberRefreshed;

        protected void OnAutoNumberRefreshed(object sender, AutoNumberRefreshedEventArgs e)
        {
            if (this.AutoNumberRefreshed != null)
            {
                this.AutoNumberRefreshed(sender, e);
            }
        }

        public event EventHandler<DocumentBackgroundChangedEventArgs> DocumentBackgroundChanged;

        protected void OnDocumentBackgroundChanged(object sender, DocumentBackgroundChangedEventArgs e)
        {
            if (DocumentBackgroundChanged != null)
            {
                DocumentBackgroundChanged(sender, e);
            }
        }

        /// <summary>
        /// 触发事件。
        /// </summary>
        /// <param name="w">必须是本页面的部件。</param>
        public void RaiseWidgetFormated(List<Widgets.Widget> formatedWidgets)
        {
            if (formatedWidgets == null || formatedWidgets.Count <= 0) return;

            OnWidgetFormated(this, new WidgetFormatedEventArgs(formatedWidgets));
        }

        public event EventHandler<WidgetFormatedEventArgs> WidgetFormated;

        protected void OnWidgetFormated(object sender, WidgetFormatedEventArgs e)
        {
            if (WidgetFormated != null)
            {
                WidgetFormated(sender, e);
            }
        }

        public event EventHandler<EventArgs> DocumentClosed;

        /// <summary>
        /// 在Build()头部触发。
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void OnDocumentClosed(object sender, EventArgs e)
        {
            if (this.DocumentClosed != null)
            {
                this.DocumentClosed(sender, e);
            }
        }

        public event EventHandler<EventArgs> DocumentOpened;

        /// <summary>
        /// 在Build()完成时触发。
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void OnDocumentOpened(object sender, EventArgs e)
        {
            if (this.DocumentOpened != null)
            {
                this.DocumentOpened(sender, e);
            }
        }

        /// <summary>
        /// 当前文档所对应的磁盘文件全路径值被改变时发生此事件。
        /// ——提供此事件是为了让主窗口有机会更新标题的文本！
        /// </summary>
        public event EventHandler<FullPathOfDiskFileChangedEventArgs> FullPathOfDiskFileChanged;

        /// <summary>
        /// 触发FullPathOfDiskFileChanged事件。
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void OnFullPathOfDiskFileChanged(object sender, FullPathOfDiskFileChangedEventArgs e)
        {
            if (FullPathOfDiskFileChanged != null)
            {
                FullPathOfDiskFileChanged(sender, e);
            }
        }

        public event EventHandler<MainSelectedWidgetChangedEventArgs> MainSelectedWidgetChanged;

        /// <summary>
        /// 触发“活动部件被改变”事件。
        /// </summary>
        protected void OnMainSelectedWidgetChanged(object sender, MainSelectedWidgetChangedEventArgs e)
        {
            if (MainSelectedWidgetChanged != null)
            {
                MainSelectedWidgetChanged(this, e);
            }
        }

        public event EventHandler<MouseLeftButtonDraggingEventArgs> MouseLeftButtonDroped;

        protected void OnMouseLeftButtonDropped(object sender, MouseLeftButtonDraggingEventArgs e)
        {
            if (MouseLeftButtonDroped != null)
            {
                MouseLeftButtonDroped(sender, e);
            }
        }

        public event EventHandler<MouseLeftButtonDraggingEventArgs> WidgetsMoved;

        protected void OnWidgetsMoved(object sender, MouseLeftButtonDraggingEventArgs e)
        {
            if (WidgetsMoved != null)
            {
                WidgetsMoved(sender, e);
            }
        }

        public event EventHandler<MouseLeftButtonDraggingEventArgs> WidgetControlerMoved;

        protected void OnWidgetControlerMoved(object sender, MouseLeftButtonDraggingEventArgs e)
        {
            if (WidgetControlerMoved != null)
            {
                WidgetControlerMoved(sender, e);
            }
        }

        #endregion

        #region 其它内容=====================================================================================================

        //枚举专门有一个文件夹来做。

        #endregion

        #region IModifingItemManager 成员

        private ModifingList<Action, ModifingInfo> modifingItemsList;

        public ModifingList<Action, ModifingInfo> ModifingItemsList
        {
            get { return modifingItemsList; }
        }

        private bool copySelectedAreaToImage = false;
        /// <summary>
        /// [读写]是否将“框选”这个操作改变为“截图”功能。为真时，pageEditor将使用截图而不是框选。
        /// </summary>
        public bool CopySelectedAreaToImage
        {
            get { return this.copySelectedAreaToImage; }
            set { this.copySelectedAreaToImage = value; }
        }

        private bool isModified = false;
        /// <summary>
        /// 表示当前文档是否已被修改。默认值为false。
        /// ——打开新文档、保存文档、新建文档后应保证此属性值为false。
        /// 
        /// 此属性值只应由NewDocument和OpenDocument、SaveDocument设置为真。
        /// 或者由其它操作设置为假。——而不应由Buid()方法设置。
        /// </summary>
        public bool IsModified
        {
            get { return isModified; }
            set { isModified = value; }
        }

        /// <summary>
        /// 是对ModifingsList类中同名方法的封装。只是为了便于使用。
        /// </summary>
        /// <param name="mi"></param>
        public void RegisterModifingItem(ModifingItem<Action, ModifingInfo> mi)
        {
            if (mi == null || mi.ActionCount <= 0) return;
            if (modifingItemsList == null) return;

            modifingItemsList.RegisterModifingItem(mi);
            this.RefreshModifingDescription();
        }

        #endregion

        #region INotifyPropertyChanged 成员

        protected void OnPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if (PropertyChanged != null)
            {
                this.PropertyChanged(sender, e);
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        #endregion


        public PageEditor PreviewMainSelectedPageEditor { get; set; }
    }

    /// <summary>
    /// 辅助线形态。
    /// </summary>
    public enum AssistGridForm
    {
        /// <summary>
        /// 无辅助线。
        /// </summary>
        None,

        /// <summary>
        /// 网格形辅助线，用于模拟字帖。
        /// </summary>
        Grid,

        /// <summary>
        /// 框形辅助线，仅显示一个虚线框，防止画到非打印区域。
        /// </summary>
        Box,

        //Mizi,       //米字格//实在无法支持，斜线在打印时和界面时总有单像素偏差冲突的问题。

        /// <summary>
        /// 田字格形的辅助线，用于模拟字帖。
        /// </summary>
        Tianzi,

        /// <summary>
        /// 回宫格形辅助线，用于模拟字帖。
        /// </summary>
        Huizi,

        /// <summary>
        /// 回宫田字格形辅助线，用于模拟字帖。
        /// </summary>
        Huitian,

        //以下为2014年2月5日新增。

        /// <summary>
        /// 两行（两个矩形区域）辅助线，用于规划版面。其中上矩形框占据总高度的1/3；下矩形框占据2/3。
        /// </summary>
        TwoLine,

        /// <summary>
        /// 两列（两个矩形区域）辅助线，用于规划版面。其中左矩形框占据总宽度的1/3；右矩形框占据2/3。
        /// </summary>
        TwoColumn,

        /// <summary>
        /// 三行（三个矩形区域）辅助线，用于规划版面。其中顶、底两个矩形框各占据总高度的1/4；中间矩形框占据1/2。
        /// </summary>
        ThreeLine,

        /// <summary>
        /// 三列（三个矩形区域）辅助线，用于规划版面。其中左、右两个矩形框各占据总宽度的1/4；中间矩形框占据1/2。
        /// </summary>
        ThreeColumn,

        /// <summary>
        /// 两行、两列共计四格，用于规划版面。四等分。
        /// </summary>
        FourCell,

        /// <summary>
        /// 传统的九宫格，但不追求高宽相等，而是三行三列将整个页面均分为九块，用于规划版面。
        /// </summary>
        NineCell,
    }

    /// <summary>
    /// 专用于FullPathOfDiskFileChanged事件的参数类。
    /// </summary>
    public class FullPathOfDiskFileChangedEventArgs : EventArgs
    {
        /// <summary>
        /// 事件发生前的值。
        /// </summary>
        public string OldFullPathOfDiskFile { get; set; }

        /// <summary>
        /// 事件发生后的值。
        /// </summary>
        public string NewFullPathOfDiskFile { get; set; }
    }

    public class AutoNumberRefreshedEventArgs : EventArgs
    {
        public List<List<Widgets.TextArea>> pageItems = new List<List<Widgets.TextArea>>();
    }
}
